Как синхронизировать потоки, находящиеся в одном блоке, но выполняющие разные операции в cuda c/c++?C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Как синхронизировать потоки, находящиеся в одном блоке, но выполняющие разные операции в cuda c/c++?

Сообщение Anonymous »

Я студент 4-го курса университета и работаю над проектом курса по параллельным вычислениям. Я принял очень плохое решение, выбрав правильный алгоритм, чтобы продемонстрировать производительность графического процессора по сравнению с его последовательным аналогом. Я выбрал алгоритм оптимизации летучей мыши, и распараллеливание выглядит следующим образом:
Поток 0: отвечает за вычисление среднего значения и применение критериев остановки путем обновления флага.
Все остальные потоки: обновление каждого свойства каждой летучей мыши в генерация/итерация популяции летучих мышей.
Сначала взгляните на код:

Код: Выделить всё

__device__ void startAlgo(Bat *bats, int N, unsigned long long seed){
__shared__ float global_best_fitness;
__shared__ float average_best_position_of_batSwarm;
__shared__ float global_best_position;
curandState *state = new curandState;  // Should ideally be per-thread and persistent, not recreated in a loop

// Initialize random states once per thread
int idx = threadIdx.x + blockIdx.x * blockDim.x;
if (idx < N) {
curand_init(seed, idx, 0, state);
}

if(threadIdx.x == 0){
setGlobalandAverage(bats, N, global_best_fitness, global_best_position, average_best_position_of_batSwarm);

while(!stopFlag){
printf("Average personal best position: %f\n",average_best_position_of_batSwarm);
float prev_avg = average_best_position_of_batSwarm;
CalculateFitnessAverage(bats, N, average_best_position_of_batSwarm);
ApplyStoppingCriteria(prev_avg, average_best_position_of_batSwarm);
//    syncThreads();  // Synchronize after potentially modifying stopFlag or other shared variables
}
} else {

while(!stopFlag){  // Ensure this check is dynamic

for(int i = threadIdx.x; i < N; i += blockDim.x * gridDim.x){  // Distribute work more evenly
performWork(&bats[i], global_best_position, state);
printf("id: %d, v: %f, p: %f, f: %f, l: %f, pr: %f, fit: %f, pbfit: %f, pbp: %f\n",i,bats[i].velocity,bats[i].position,bats[i].frequency,bats[i].loudness,bats[i].pulse_rate,bats[i].fitness,bats[i].personal_best_fitness,bats[i].personal_best_position);

}
__syncthreads();  // Sync all threads to recheck the stopping flag
}
}

delete state;  // Clean up the state
}

Эта функция вызывается после инициализации.
Я подтвердил тот факт, что каждый поток действительно входит в функцию, но происходит то, что только поток 0 выполняет свою работу в цикле, и поскольку в популяции Bat нет обновлений, программа, как следствие, останавливается. Я также подтвердил, что это не имеет никакого отношения к тому факту, что поток 0 запускается первым или что-то в этом роде. Я даже пытался добавить механизм ожидания, чтобы проверить, начнут ли остальные потоки выполнять свою работу хотя бы один раз, но безуспешно. Я понимаю, что может быть много ошибок новичков, но поскольку я работаю в Windows, я не могу отлаживать программы cuda.

Подробнее здесь: https://stackoverflow.com/questions/785 ... -operation
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»