我需要通过在不同情况下测试它们的吞吐量来测试一些GPU。
这包括一个简单的64b乘法:
__device__ void add(unsigned int *data, bool flag){
unsigned int index = threadIdx.x;
unsigned int result;
asm ("{\n\t"
"add.cc.u32 %1, %1, %1;\n\t"
"addc.u32 %0, 0, 0;\n\t"
"}"
: "=r"(result), "+r"(index): );
if(flag)
data[threadIdx.x] = result;
}
64b模数:
__device__ void mod(){
asm ("{\n\t"
".reg .u64 t1;\n\t"
"cvt.u64.u32 t1, %0;\n\t"
"rem.u64 t1, t1, t1;\n\t"
"}"
: : "r"(index));
}
和64b mul + mod:
__device__ void mulmod
asm ("{\n\t"
".reg .u64 t1;\n\t"
".reg .u64 t2;\n\t"
"mul.wide.u32 t1, %0, %0;\n\t"
"cvt.u64.u32 t2, %0;\n\t"
"rem.u64 t1, t1, t2;\n\t"
"}"
: : "r"(index));
}
我认为任何内存访问对我的意图都是完全没用的,我想用线程索引变量作为输入。
因为我要写无寄存器,所以我不需要关心寄存器的使用情况,我可以启动尽可能多的线程(每个GPU允许)
我想知道:
如果这是正确的方法
是否有任何特定的线程配置,除了最大化线程数,我可以检索最佳吞吐量?
答案 0 :(得分:2)
你的第一个“子问题”的答案是不是这不是正确的方法,因为你编写的那些函数都不会被编译器发出。
您可以在上面链接的问题中查看my answer中的更多详细信息,但简短版本是C编译器级死代码优化将消除任何不参与写入的值的代码记忆。因此,您必须让这些函数返回一个值,并且必须使用返回值,使编译器无法推断出对设备函数的调用是多余的并消除它。
除此之外,每个SM必须有足够的活动warp来分摊架构中的所有指令调度延迟,并确保测量设备函数的指令吞吐量,而不是指令调度程序和管道的延迟。