我正在使用最新的CUDA 8.0和GTX 1080,并运行样本来测试速度。 (我知道它们没有反映出最佳速度,但我只是想横向比较。)
在0_Simple/matrixMul
中,速度由代码测量,它给出:
Performance= 1029.91 GFlop/s, Time= 0.127 msec, Size= 131072000 Ops, WorkgroupSize= 1024 threads/block
然后我运行0_Simple/vectorAdd
,并从上面的示例中复制速度测试代码。即:
// Measure speed
cudaEvent_t start;
cudaEventCreate(&start);
cudaEvent_t stop;
cudaEventCreate(&stop);
cudaEventRecord(start, NULL);
int nIter = 300;
for (int i = 0; i < nIter; i++) {
vectorAdd<<<blocksPerGrid, threadsPerBlock>>>(d_A, d_B, d_C, numElements);
}
cudaEventRecord(stop, NULL);
cudaEventSynchronize(stop);
float msecTotal = 0.0f;
cudaEventElapsedTime(&msecTotal, start, stop);
float msecPerAdd = msecTotal / nIter;
double flopsPerAdd = numElements;
double gigaFlops = (flopsPerAdd * 1.0e-9f) / (msecPerAdd / 1000.0f);
printf("Performance= %.2f GFLOPS, Time= %.3f ms, Size= %.0f Ops\n", gigaFlops, msecPerAdd, flopsPerAdd);
我还将numElements
从50000
放大到67108864
。速度结果是:
Performance= 19.85 GFLOPS, Time= 3.380 ms, Size= 67108864 Ops
慢了近5倍。
我知道示例代码可能不是最理想的,所以有人能告诉我为什么vectorAdd代码太慢了,以及如何优化它?
我正在使用CUDA 8.0和GTX 1080
答案 0 :(得分:3)
与矩阵乘法不同,向量加法是一种内存带宽绑定操作。衡量其性能的正确方法是测量全局内存访问的带宽。对于向量加法,它包括2个输入和1个输出向量,并且可以如下计算。
3 * numElements * sizeof(d_A[0]) / kernel_running_time
您可以将其与简单D2D副本的带宽进行比较,看看您是否已达到峰值。
答案 1 :(得分:-1)
编辑:添加了GPU和CPU的代码
我运行以下实验
*** Cuda内核
__global__ void add(float *a, float *c , size_t N)
{
int tid = blockIdx.x*blockDim.x + threadIdx.x;
if(tid < N) a[tid] += c[tid];
}
*** CPU天真版本(基线)
void naiveAdd(float *h_a, float *h_c, size_t N)
{
for (size_t i=0; i<N; i++)
h_a[i] += h_c[i];
}
用于在具有不同CUDA GCC版本的同一机器(740M GPU,第4代i7)中添加两个向量的性能比较。
有了这个证据,我可以得出结论,目前最好避免使用CUDA 8.0。