Cuda 为什么维度的顺序对性能有很大影响?

Cuda 为什么维度的顺序对性能有很大影响?,cuda,parallel-processing,Cuda,Parallel Processing,要启动CUDA内核,我们使用dim3来指定维度,我认为每个维度的含义由用户选择,例如,它可能表示(宽度、高度)或(行、列),其含义相反 所以我用SDK中的CUDA示例做了一个实验:3_Imaging/ConvolutionsSeparable,在内核函数中简单地交换.x和.y,并反转用于启动内核的块和线程的维度,因此含义从dim(width,height)/idx(x,y)变为dim(rows,cols)/idx(row,col) 结果是一样的,但是性能下降了,原来的大约需要26毫秒,而在我的机

要启动CUDA内核,我们使用
dim3
来指定维度,我认为每个维度的含义由用户选择,例如,它可能表示(宽度、高度)或(行、列),其含义相反

所以我用SDK中的CUDA示例做了一个实验:3_Imaging/ConvolutionsSeparable,在内核函数中简单地交换.x和.y,并反转用于启动内核的块和线程的维度,因此含义从dim(width,height)/idx(x,y)变为dim(rows,cols)/idx(row,col)

结果是一样的,但是性能下降了,原来的大约需要26毫秒,而在我的机器(SM 3.0)上修改的大约需要40毫秒

我的问题是,有什么区别?(行、列)对CUDA不可行吗

p.S.I只修改了卷积行,没有卷积列


编辑:可以找到更改。

您的更改至少有两个潜在后果:

  • 首先,将内存访问模式更改为主内存,以便 访问不像最初的情况那样合并

    您应该以与以前相同的方式考虑GPU主内存 “CPU”内存,即预取、阻塞、顺序访问。。。 应用技术以获得性能

    如果你想了解更多关于这个主题的信息,必须阅读 这篇论文。 您将看到一个比较行和列的示例 访问矩阵中的元素

    要了解和了解这一点有多重要,请思考最重要的一点——如果不是的话 所有GPU高性能代码执行矩阵变换 在进行任何计算之前,为了获得更统一的内存 访问,而且这一额外的步骤在条款上仍然是值得的 演出(例如,稀疏矩阵运算)

  • 第二。这更微妙,但在某些情况下,它会对内核的性能产生深刻的影响;启动配置。启动20块10线程与启动10块20线程不同。线程所需的资源量(共享内存、寄存器数量等)存在很大差异。线程需要的资源越多,可以映射到单个SM上的扭曲就越少,因此占用率就越低。。。而且,大多数情况下,性能较差。 这不适用于您的问题,因为块的数量等于线程的数量


  • 为GPU编程时,您必须了解体系结构,以了解这些更改将如何修改性能。当然,我对代码不熟悉,所以这两个因素中还有其他因素。

    你的内核启动配置是什么?@kronos,它们被转换了,例如dim3(a,b)变成了dim3(b,a)。我对引用的代码不熟悉,但一般来说,这种线程块配置转置与内存子系统交互,因为多维线程块以特定的方式映射到全局线程索引。通常,您希望x维中的单位步长与数组元素中的单位步长相对应,以获得最佳性能。我建议使用探查器检查共享和全局内存事件,以深入了解您的具体案例的两种变体。@Jamboree,是的,我从您的问题中了解到这一点,但实际数字是多少?例如:32x8(通常)会产生比8x32更好的内存访问模式,因为warp中的所有线程都会合并访问全局内存。在更改前后提供代码非常有用,因为问题是我们只能猜测。内存访问模式是问题所在,第2点不是问题,因为配置大小相同。你完全正确。我将更改答案以指定这一点。