我试图减少65536个元素数组(计算它的元素的总和)与CUDA的帮助。内核看上去像下面(请无视* dev_distanceFloats和索引参数现在)CUDA:写入共享内存increses内核时执行了很多
__global__ void kernel_calcSum(float *d, float *dev_distanceFloats, int index) {
int tid = threadIdx.x;
float mySum = 0;
for (int e = 0; e < 256; e++) {
mySum += d[tid + e];
}
}
蚂蚁又推出作为一个块与256个线程:
kernel_calcSum <<<1, 256 >>>(dev_spFloats1, dev_distanceFloats, index);
到目前为止,一切都很好,每256个线程从全局内存获取256个元素,并在局部变量mySum中计算总和。内核执行时间约为45毫秒。 下一步是介绍共享存储器那些256个线程之间的块(以计算mySum的总和),因此内核变为如下:
__global__ void kernel_calcSum(float *d, float *dev_distanceFloats, int index) {
__shared__ float sdata[256];
int tid = threadIdx.x;
float mySum = 0;
for (int e = 0; e < 256; e++) {
mySum += d[tid + e];
}
sdata[tid] = mySum;
}
我刚添加写入共享存储器,但是从45毫秒执行时间的增加到258毫秒(我正在借助NVidia Visual Profiler 5.0.0来操作)。 我认识到,有8个为每个线程冲突写SDATA变量(我上有32个存储能力3.0 GTX670)时。作为一个实验 - 我试图在启动内核时将线程数减少到32,但时间仍然是258毫秒。
问题1:为什么写入共享内存需要很长时间在我的情况? 问题2:是否有任何工具,详细显示有点“执行计划”(内存访问时间,冲突等)?
感谢您的建议。
更新: 内核打 - 我设置SDATA某个常数为每个线程:
__global__ void kernel_calcSum(float *d, float *dev_distanceFloats, int index) {
__shared__ float sdata[256];
int tid = threadIdx.x;
float mySum = 0;
for (int e = 0; e < 256; e++) {
mySum += d[tid + e];
}
sdata[tid] = 111;
}
和时间又回到了48毫秒。 所以,改变 SDATA [TID] = mySum; 至 sdata [tid] = 111; 做了这个。
这是编译器优化(可能只是删除了这一行吗?)或者由于某些原因从本地内存(register?)复制到共享需要很长时间?
我明白了。所以,据我了解 - 事实上在第一种情况下,cuda运行空内核(因为编译器决定不会在任何情况下使用结果)?在第二种情况下,内核代码不是空的,并且对于内存访问和其他正常的事情,时间增加到258毫秒,对吧? – Arsen 2013-03-15 11:12:26
是的,没错。 – tera 2013-03-15 11:16:56
谢谢,泰拉!这对我来说看起来是真的。 – Arsen 2013-03-15 11:22:54