简单示例中的CUDA内核调用

简单示例中的CUDA内核调用,cuda,Cuda,这是cuda的第一个示例并行代码 有谁能描述一下内核调用:> 这是代码,其中有重要的几点: #define N 10 __global__ void add( int *a, int *b, int *c ) { int tid = blockIdx.x; // this thread handles the data at its thread id if (tid < N) c[tid] = a[tid] + b[tid]; } int m

这是cuda的第一个示例并行代码

有谁能描述一下内核调用:>

这是代码,其中有重要的几点:

#define N   10

__global__ void add( int *a, int *b, int *c ) {
    int tid = blockIdx.x;    // this thread handles the data at its thread id
    if (tid < N)
        c[tid] = a[tid] + b[tid];
}

int main( void ) {
    int a[N], b[N], c[N];
    int *dev_a, *dev_b, *dev_c;

    // allocate the memory on the GPU
    // fill the arrays 'a' and 'b' on the CPU
    // copy the arrays 'a' and 'b' to the GPU

    add<<<N,1>>>( dev_a, dev_b, dev_c );

    // copy the array 'c' back from the GPU to the CPU
    // display the results
    // free the memory allocated on the GPU

    return 0;
}
#定义N 10
__全局无效添加(int*a、int*b、int*c){
int tid=blockIdx.x;//此线程在其线程id处处理数据
如果(tid

为什么它使用了
,这意味着我们在每个块中使用了N个块和1个线程??因为我们可以编写这个
,并在这个块中使用1个块和N个线程来进行更多优化

对于这个小例子,没有特别的原因(巴特在评论中已经告诉过你)。但对于更大、更现实的示例,您应该始终记住,每个块的线程数是有限的。也就是说,如果使用N=10000,就不能再使用
,但是
仍然可以工作。

没有特别的原因。这是书中试图解释GPU向量和的第一个例子之一。最佳性能或任何这样的概念在当时几乎不在他们的脑海中。这是一个简单的说明性例子。这就是全部。正如开头的目标所述,“你将用CUDA C编写你的第一个并行代码”。网格大小也有限制。@chaohuang是的,也有限制-我没有提到这一点,因为我不想让我的回答太混乱,但你当然是对的,这是一个重要的事实!但是,最大网格大小远远大于每个网格块的线程数。对不起。如果要使用
且N小于块限制,则必须使用
threadIdx
而不是
blockIdx
?还有一个问题:如果我想使用
,有人能帮我编写add函数吗?@mehD是的,如果
使用
blockIdx
,则必须使用
threadIdx
。对于您的示例,
可以这样计算索引:
uint idx=blockIdx.x*blockDim.x+threadIdx.x。但是,您必须始终检查索引的边界:如果N是奇数,例如5,由于舍入,您将得到
(=4)。如果你凑齐,你会得到
(=6)。在这种情况下,您必须检查内核中的索引(例如,
if(idx>=5)return;
)。看看英伟达GPU计算SDK中的例子,它们真的很有帮助和启发性!