Конфликтный доступ к памяти в cuda8 (GPU)
Во имя Аллаха
желаю хорошо провести время дорогие друзья
Я работаю над программированием GPU с cuda8, и я новичок.
Я знаю параллельное программирование и работал с конфликтом памяти доступа (состояние гонки) в памяти процессора.
Что я уже пробовал:
Когда мы пронизываем программу в процессоре, если мы делаем это таким образом, мы получим ошибку состояния гонки :
#include <thread> using namespace std; int16_t* buffer = nullptr; void function(int16_t* _buffer){ _buffer[0] = 1; } void main(){ buffer = new int16_t[10]; thread threads[10]; for (int16_t tIndex = 0; tIndex < 10; tIndex++){ threads[tIndex] = thread(function, buffer); } for (int16_t tIndex = 0; tIndex < 10; tIndex++){ threads[tIndex].joinable(); threads[tIndex].join(); } }
Это истинная материя, и мы должны предотвратить возникновение этой проблемы, например, использовать мьютекс или атомарный тип данных.
Проблема в том, что когда я делаю это в Cuda (GPU programming) Намеренно этого не произойдет, я задавался вопросом и хочу знать почему?
Мой код ядра cuda, который я тестировал, таков :
__global__ void CudaKernel(int* _buffer){ int id = threadIdx.x; _buffer[0]++; }
Я вызывал эту функцию ядра несколько раз, например 1000 или... но конфликт доступа к памяти не был замечен, и только один поток увеличивает значение _buffer[0].
Не могли бы вы объяснить мне, почему?
в моем файле .cu я вызываю ядро, как показано ниже :
dim3 blocks(10, 1, 1); dim3 grids(1, 1, 1); CudaKernel <<<1, blocks >>>(cudaBuffer); //Checking launching error result = cudaGetLastError(); if (cudaSuccess != result){ cout << "Launching the kernel has failed. error : " << result << "\n"; goto end; } //Waiting to synchronize all of threads to finish result = cudaDeviceSynchronize(); if (cudaSuccess != result){ cout << "Failed to synchronize with error " << result << endl; goto end; }
спасибо в adcance
Jochen Arndt
Я не знаю CUDA, поэтому не могу ответить.
Но я предлагаю использовать более сложную операцию, потому что
_buffer[0]++;
это может быть атомарная операция (одна команда GPU).
Mahdi Nejadsahebi
я также вел себя так, как показано ниже :
_buffer[0] = _buffer[0] + 1;
но проблема есть.