CUDA。示例表示性能如何取决于线程数

时间:2012-10-06 12:27:38

标签: cuda

我认为,可以并行运行的线程/块的数量是有限的。我的意思是,如果我有太多线程/块,其中一些将在某些处理单元上顺序执行。我需要构建下一个示例。比方说,我有一些kernel<<<B, N>>>()kernel<<<1,1>>>()的执行时间等于t0。

第一个任务是找到B和N的最大值,即kernel<<<B, N>>>() t~t0的执行时间。然后我希望执行时间为kernel<<<B, 2*N>>>()(或kernel<<<2*B, N>>>())t1~2 * t。

我有特斯拉C2075,配有448个CUDA核心(14个SM),并希望以占用率1为例。

这是可能的吗?如果是的话,内核函数应该如何显示,可能是一些例子?

1 个答案:

答案 0 :(得分:0)

在CUDA中,线程被安排在单个SM上作为warp。每个warp最多可以包含32个线程。调度程序将尝试在SM中以并行方式执行warp。如果特定warp的数据没有准备好,它将由调度程序保存,直到它可用为止。现在,您的问题是关注的,我相信可以使用cudaEvent_t(用于测量内核的执行时间)来实现您要实现的目标。

kernel<<<B,Tnum>>>(arg1...argn);的启动配置完全取决于您在算法中可以利用多少并行度。此外,线程数是您必须根据启动内核获得的最佳执行时间来决定的。

在许多情况下,使用128/256个线程启动多个块就足以实现最佳加速。举一个例子,假设我们要将两个大小为1024的数组的单个元素添加到第三个数组中,带有1个块的内核函数看起来像

__global__ void kadd(int *c,int *a,int *b)
{
  unsigned int tid = threadIdx.x;//Since only one block of 1024 threads suffices
  if(tid < MAXNUM)  //MAXNUM = 1024
    c[tid] = a[tid]+ b[tid];
}

启动配置将是

kadd<<<1,1024>>>(c,a,b);

然而,这只会在你的GPU的一个SM上执行一个块,这意味着你没有完全利用GPU资源。要从GPU中获得更多,您可以做的就是 使用多个块和线程。内核看起来像

__global__ void kadd(int *c,int *a,int *b)
{
  unsigned int tid = blockIDx.x * blockDim.x + threadIdx.x;//Since multiple blocks are used
  if(tid < MAXNUM)  //MAXNUM = 1024
    c[tid] = a[tid]+ b[tid];
}

,相应的启动配置为

kadd<<<8,128>>>(c,a,b);

这将分别启动8128个线程块。您可以根据算法要求使用此启动配置。您可以通过启动2D3D网格来进一步探索这些启动配置,以充分利用您的GPU。

因此,内核计时将为您提供最适合您要求的配置。这也将根据共享内存的使用,全局内存的合并访问和其他因素而改变。 最后,我想提一下NVIDIA提供的占用计算器,您可以使用它来找到块和线程的最佳组合,以实现更高的占用率。