Cuda:GTX 460的架构和网格/块/线程的代码相关分离

时间:2011-04-28 21:36:59

标签: architecture cuda

嘿那里, 到目前为止,我所了解的内容如下:GTX460 1GB(GF104)有2GPC,每个4个SM,因此8SM共计1个被禁用,这意味着:7SM(“流多处理器”)。每个SM有48个Cuda核心(这就是我们所说的线程吗?它可以理解为像Q9550-Quadcore这样的CPU的核心?),所以共有336个Cuda核心。

所以我现在还不明白:为什么这个'复杂'的架构不仅仅像在CPU上说的那样:'好吧,GPU有N核,就是这样!'?

假设我有一个特定的程序被分成B块的网格和每个T线程的块(总共B * T个线程),我可以告诉你一个块总是连接到ONE SM还是NOT?因为如果它是这样的话,这将使编码器变得更难,因为他应该知道有多少SM来优化每个图形卡的并行化。例如:当我有一个带有8个SM的图形卡时,我的程序只会将数据分成带有N个线程的1个块的网格,我只能使用一个不会使用其所有资源的SM!

在编写程序时,有没有办法只使用卡的某些线程?我真的很想通过在1..M线程上运行我的程序来对加速进行基准测试,其中M是cuda核心的总数(如果这相当于'thread'),但是如何做到这一点?这样编写我的程序就足够了:

cudaKernel<<<1, 1>>>(...)

cudaKernel<<<1, M>>>(...)

每次运行它?我在这里看到的唯一问题是:让我们假设我有简单的向量加法示例:

#define SIZE 10
__global__ void vecAdd(float* A, float* B, float* C)
{
   int i = threadIdx.x;
   A[i]=0; 
   B[i]=i;
   C[i] = A[i] + B[i];
}
int main()
{
    int N=SIZE;
    float A[SIZE], B[SIZE], C[SIZE];
    // Kernel invocation

    float *devPtrA;
    float *devPtrB;
    float *devPtrC;
    [...]
    vecAdd<<<1, N>>>(devPtrA, devPtrB, devPtrC);
}

当我现在将vecAdd<<<1, N>>>设置为vecAdd<<<1, 1>>>时,单个线程不会将C计算为N大小的向量,因为唯一的线程只计算A,B的第一个值,因此C如何克服这个问题呢? 非常感谢您提前澄清!!你会帮助我很多!

1 个答案:

答案 0 :(得分:2)

在大多数情况下,你所询问的大多数问题的答案都是否定的。不只是,但是没有。

大多数GPU编程的一般想法是它应该是隐式可伸缩的 - 即,您的代码会自动使用尽可能多的内核。特别是,当它用于图形处理时,核心在执行三种类型的着色器(顶点,几何,片段/像素)之间分离。因此,可用核心的数量可以(并且通常会)动态变化,具体取决于总体负载。

以这种方式组织GPU有几个原因,而不是像典型的多核CPU那样。首先,它主要用于“令人尴尬的并行”问题 - 显然,其主要目的是将相似的代码应用于大量像素中的每一个。虽然在使用CUDA代码时你并没有完全相同,但这仍然是硬件设计的基础。其次,如上所述,核心实际上在至少三个不同目的之间分开,并且可以在更多核心之间分开(例如,使用某些核心的图形应用程序,以及使用其他核心的CUDA代码)。第三,额外的抽象有助于保持代码免受硬件变化的影响。它允许您仅指定所需的计算,并且它可以尽可能高效地在硬件上进行调度。