Architecture Cuda:GTX460的体系结构和与代码相关的网格/块/线程分离

Architecture Cuda:GTX460的体系结构和与代码相关的网格/块/线程分离,architecture,cuda,Architecture,Cuda,嘿,那里, 到目前为止,我所了解的是:GTX460 1GB(GF104)有2GPC,每个2GPC有4条短信,因此总共有8条短信,其中1条被禁用,这意味着:7SM(“流式多处理器”)。每个SM有48个Cuda内核(这就是我们所说的线程吗?它可以理解为CPU的一个内核,比如Q9550四核吗?),因此总共有336个Cuda内核 所以我现在不明白的是:为什么这种“复杂”的体系结构,而不仅仅像在CPU上说:‘好吧,GPU有N个内核,就是这样!’ 假设我有一个特定的程序,它被划分成一个由B块和每个T线程块组

嘿,那里, 到目前为止,我所了解的是:GTX460 1GB(GF104)有2GPC,每个2GPC有4条短信,因此总共有8条短信,其中1条被禁用,这意味着:7SM(“流式多处理器”)。每个SM有48个Cuda内核(这就是我们所说的线程吗?它可以理解为CPU的一个内核,比如Q9550四核吗?),因此总共有336个Cuda内核

所以我现在不明白的是:为什么这种“复杂”的体系结构,而不仅仅像在CPU上说:‘好吧,GPU有N个内核,就是这样!’

假设我有一个特定的程序,它被划分成一个由B块和每个T线程块组成的网格(总共是B*T线程),我能告诉你一个块是否总是连接到一个SM吗?因为如果是这样的话,这将使编码人员更加困难,因为他应该知道有多少短信可以优化每个图形卡的并行化。例如:如果我有一个8 SM的图形卡,而我的程序只能将数据分割成一个由1个块和N个线程组成的网格,那么我只能使用一个SM,而不会使用它的所有资源

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

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

cudaKernel(…)
每次都运行它?我在这里看到的唯一问题是:假设我有一个简单的向量加法示例:

#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);
}
#定义尺寸10
__全局无效向量添加(浮点*A、浮点*B、浮点*C)
{
int i=threadIdx.x;
A[i]=0;
B[i]=i;
C[i]=A[i]+B[i];
}
int main()
{
int N=大小;
浮动A[大小]、B[大小]、C[大小];
//内核调用
浮动*devPtrA;
浮动*devPtrB;
浮动*devPtrC;
[...]
vecAdd(devPtrA、devPtrB、devPtrC);
}
当我现在将
vecAdd
设置为
vecAdd
时,单个线程不会将C计算为N大小的向量,因为唯一的线程只会计算a、B的第一个值,从而计算C。如何克服这个问题?
非常感谢您提前澄清!!你会帮我很多的

在大多数情况下,你所问的大部分问题的答案都是否定的。不仅仅是否定,而且是否定

大多数GPU编程的总体思想是,它应该是隐式可伸缩的——也就是说,您的代码会自动使用给定数量的内核。特别是,当用于图形处理时,核心会在执行三种类型的着色器(顶点、几何体、片段/像素)之间分离。因此,根据总体负载,可用内核的数量可以(并且通常会)动态变化


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

谢谢。假设一个线程与cuda内核(与四核CPU的4个内核中的一个相同)相同,对吗?进一步:在我的示例中,是否有可能限制程序中的线程数量以及如何做到这一点?@bjoern:没有。线程与内核不同。线程是CUDA中最小的虚拟化并行工作单元。作为一名程序员,您可以明确控制运行的线程数量,但不能控制这些线程与物理硬件的关系。好的,当有336个Cuda内核时,我如何知道GTX460上的最大线程数量?每个内核的线程数是否固定?GTX460上的最大线程数为1024*65535*65535*65535=28827182213504000。CUDA中没有单核线程限制,硬件的所有方面都抽象在编程模型中。您可以有65535^3个块,每个块最多可以有1024个线程。块分布在GPU中的多处理器上,这些处理器以类似于现代x86处理器上SIMD单元的方式运行这些块中的线程。内核的数量以及与执行的关系与编程模型无关。嗯,到目前为止,这听起来有点让我困惑。。。有没有办法“限制”线程数,使我只能使用5%、10%、15%…100%的GPU资源来测试程序的加速?谢谢
#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);
}