Я хочу узнать, как количество потоков в блоке влияет на производительность и скорость программы cuda. Я написал простой код векторного сложения, вот мой код:Эксперимент, чтобы узнать влияние размера блока на скорость программы cuda
#define gpuErrchk(ans) { gpuAssert((ans), __FILE__, __LINE__); }
inline void gpuAssert(cudaError_t code, const char *file, int line, bool abort=true)
{
if (code != cudaSuccess)
{
fprintf(stderr,"GPUassert: %s %s %d\n", cudaGetErrorString(code), file, line);
if (abort) exit(code);
}
}
__global__ void gpuVecAdd(float *a, float *b, float *c, int n) {
int id = blockIdx.x * blockDim.x + threadIdx.x;
if (id < n) {
c[id] = a[id] + b[id];
}
}
int main() {
int n = 1000000;
float *h_a, *h_b, *h_c, *t;
srand(time(NULL));
size_t bytes = n* sizeof(float);
h_a = (float*) malloc(bytes);
h_b = (float*) malloc(bytes);
h_c = (float*) malloc(bytes);
for (int i=0; i<n; i++)
{
h_a[i] =rand()%10;
h_b[i] =rand()%10;
}
float *d_a, *d_b, *d_c;
cudaMalloc(&d_a, bytes);
cudaMalloc(&d_b, bytes);
cudaMalloc(&d_c, bytes);
gpuErrchk(cudaMemcpy(d_a, h_a, bytes, cudaMemcpyHostToDevice));
gpuErrchk(cudaMemcpy(d_b, h_b, bytes, cudaMemcpyHostToDevice));
clock_t t1,t2;
t1 = clock();
int block_size = 1024;
gpuVecAdd<<<ceil(float(n/block_size)),block_size>>>(d_a, d_b, d_c, n);
gpuErrchk(cudaPeekAtLastError());
t2 = clock();
cout<<(float)(t2-t1)/CLOCKS_PER_SEC<<" seconds";
gpuErrchk(cudaMemcpy(h_c, d_c, bytes, cudaMemcpyDeviceToHost));
cudaFree(d_a);
cudaFree(d_b);
cudaFree(d_c);
free(h_a);
free(h_b);
free(h_c);
}
Я прочитал this post и на основе ответить на talonmies "Количество потоков на блок должен быть круглым кратен размеру основы, которая 32 на все текущее оборудование «
Я проверил код с различным количеством потоков на блок, например, 2 и 1024 (что умножается на 32, а также максимальное количество потоков на блок). Среднее время работы для обоих размеров почти одинаковое, и я не вижу огромной разницы между ними. Почему это? Является ли мой бенчмаркинг неправильным?
Вы только накладные расходы на запуск. На самом деле вы не определяете продолжительность ядра. После вызова 'cudaPeekAtLastError' добавьте вызов' cudaDeviceSynchronize() ', который заставит всю продолжительность ядра отображаться в вашем времени. –
@RobertCrovella Да! это была проблема. Пожалуйста, напишите свой ответ, чтобы я мог отметить его как правильный ответ. – starrr