我制作了一些用于测试带宽的内核,但它们没有进行有用的计算。最小的例子是
__global__ void testKernel(float* a)
{
unsigned int i = blockIdx.x*blockDim.x + threadIdx.x;
float x;
x = a[i];
}
当我编译时,我得到(并不奇怪)
警告:变量“x”已设置但从未使用过
并且内核的运行速度与空内核一样快:
__global__ void donothing()
{
}
这表明a [i]的读取已被优化。
我尝试了诸如
之类的技巧volatile float x;
if(x);
(void)(x;)
并且他们禁止警告,但内核仍然完成得太快。
如何确保无用的指令实际执行?
我找到了CU_JIT_OPTIMIZATION_LEVEL选项,但google主要提供了文档的链接,而不是如何使用它。这个选项会帮助我,我该如何使用它?
答案 0 :(得分:2)
尝试引入存储变量的分支:
__global__ void testKernel(float* a, float *b)
{
unsigned int i = blockIdx.x*blockDim.x + threadIdx.x;
float x;
x = a[i];
if(b)
{
*b = x;
}
}
与内存传输成本相比,分支的成本可以忽略不计。
在内核启动站点,只需传递一个空指针:
testKernel<<<...>>>(a, static_cast<float*>(0));
nvcc不会以此粒度执行constant folding,因此不应删除您的负载,因为编译器无法证明它没用。