У меня есть следующие ядра:Cuda атомарные операции
__global__
void collect_boundary(const int64_t* cvert, const csr_node* neighb, const bool* affected, int64_t* parent, const uint64_t* dist, uint64_t* ndist, bool* mask, int64_t numvertices){
int64_t tid = blockIdx.x*blockDim.x + threadIdx.x;
if(tid >= numvertices || affected[tid] || dist[tid]==MY_INFINITY)
return;
for(int64_t index = cvert[tid]; index<cvert[tid+1]; index++){
auto vtex = neighb[index];
if(affected[vtex.head]){
int64_t ndistent = dist[tid] + vtex.weight;
atomicMin((unsigned long long int*)(ndist + vtex.head),(unsigned long long int)ndistent);
/*if(ndist[vtex.head] == ndistent){
parent[vtex.head] = tid;
}*/
}
}
}
В основном я хотел каждая нить вычислить ndistent как данность и я обновить ndist [vtex.head] как минимум всех ndistents.
Я достиг этого с помощью:
atomicMin((unsigned long long int*)(ndist + vtex.head),(unsigned long long int)ndistent);
//That is each thread will update ndist[vtex.head] if and only if
//it's own value of ndistent is less than the ndist[vtex.head]
//which was initialized to INFINITY before the kernel launch
Но теперь я хотел сохранить TID, который дает минимальную ndistent.
Я пытался что-то вроде этого
if(ndist[vtex.head] == ndistent){ // prob_condition 1
parent[vtex.head] = tid; // prob_statment 1
}
//That is each thread will check wether the value in
//ndist[vtex.head] is equal to it's own ndistent
// and then store the tid if it is.
Это выше фрагмент кода не будет работать, потому что некоторые нить X может обнаружить, что prob_condition 1, чтобы быть правдой, но, прежде чем он выполняет prob_statement 1 допустим нить, которая даст минимальное значение скажем, что нить Y выполняет prob_statement 1 и сохраняет его. Теперь поток X возобновится и сохранит его, поэтому min tid будет потерян.
Поэтому я хочу, чтобы prob_condition 1 и prob_statement 1 выполнялись атомарно.
Или же мне нужно сделать следующие 3 opertaions атомарно:
Проверьте, ndistent < ndist [vtex.head]
обновление ndist [vtex.head]
хранить tid в исходном состоянии [vtex.head]
У кого-нибудь есть предложения, как я могу это сделать?
EDIT: Обратите внимание, что мне нужно будет запустить это ядро с переменным числом блоков и числом переменных.