CUDA-这个循环在做什么
哎 我在一个网站上看到了这个内核示例CUDA-这个循环在做什么,cuda,Cuda,哎 我在一个网站上看到了这个内核示例 __global__ void loop1( int N, float alpha, float* x, float* y ) { int i; int i0 = blockIdx.x*blockDim.x + threadIdx.x; for(i=i0;i<N;i+=blockDim.x*gridDim.x) { y[i] = alpha*x[i] + y[i]; } } \uuuu全局\uuuuu无
__global__ void loop1( int N, float alpha, float* x, float* y ) {
int i;
int i0 = blockIdx.x*blockDim.x + threadIdx.x;
for(i=i0;i<N;i+=blockDim.x*gridDim.x) {
y[i] = alpha*x[i] + y[i];
}
}
\uuuu全局\uuuuu无效循环1(整数N、浮点alpha、浮点*x、浮点*y){
int i;
int i0=blockIdx.x*blockDim.x+threadIdx.x;
对于(i=i0;i
因此,假设gridDim.x=1
如果向量的入口比已启动的线程多,则需要内核中的for循环。如果可能,启动足够多的线程当然更有效。有趣的内核。内核中的循环是必要的,因为N大于线程总数,这是16384(blockDim.x*gridDim.x),但我认为这样做不是好的做法(CUDA的全部要点是使用SIMT概念)。根据CUDA编程指南,一个内核最多可以有65535个线程块。此外,从Compute Capability 2.x(费米)开始每个块最多可以有1024个线程(费米之前为512个),也可以(如果可能)将代码分成多个(顺序的)内核。尽管我们相信CUDA GPU有无限的执行资源,但它们没有,而且高度优化代码的作者发现,通常具有固定块数的循环展开可以提供最佳性能。这会导致痛苦的编码,但优化的CPU代码也相当痛苦
顺便说一句,一位评论员提到这段代码会有合并问题,我不明白为什么。如果基址正确对齐(64B,因为它们是浮点数),如果线程/块也可以被64整除,则此代码的所有内存事务都将合并。啊,我明白了,所以在这种情况下,如果N大于64*256,则需要合并。非常感谢实际使用这样的内核执行配置>gridDim。x值是64,而不是1,因为gridDim内置在dim3变量中包含维度of网格和该网格有64个使用一维的线程块。有时,最好有一个易于展开的for循环(在本例中是这样),而不是启动太多的块并不断切换它们。可以根据经验为给定问题找到最佳数量。@Pavan ok,但我认为这也是(全局的)内存访问可以在for循环中优化。在上面的示例中,y[i]=alpha*x[i]+y[i];迭代非常分散(i0,i0+numberOfThreads,i0+2*numberOfThreads,…)。Szepetkowski,你是对的。我通常使用for循环访问连续的数据块,所以我从来没有这样想过:)
for(i=0;i<N;i++) {
y[i] = alpha*x[i] + y[i];
}