我用第一矩阵非转置和第二转置调用cublas_Sgemm_v2函数10236次。但是,在nvprof结果中,我看到了该函数调用产生的三个项。函数调用的(m,n,k)值为(588,588,20)。
nvprof结果中列出了一些项。
Time(%) Time Calls Avg Min Max Name
12.32% 494.86ms 10236 48.344us 47.649us 49.888us sgemm_sm35_ldg_nt_128x8x128x16x16
8.64% 346.91ms 10236 33.890us 32.352us 35.488us sgemm_sm35_ldg_nt_64x16x128x8x32
8.11% 325.63ms 10236 31.811us 31.360us 32.512us sgemm_sm35_ldg_nt_128x16x64x16x16这是意料之中的,为什么呢?有人能解释一下函数名(如sgemm_sm35_ldg_nt_128x8x128x16x16 )中的值是什么意思吗?
我还使用不同的转置设置对cublas_Sgemm_v2进行其他函数调用,每个函数调用只看到一个项。
更新:
正如@Marco13 13所问的,我在这里发表了更多的结果:
Time(%) Time Calls Avg Min Max Name
--------------------------------------------------------------------------------
Resulted from 7984 calls with (Trans, NonTrans) with (m, n, k) = (588, 100, 588)
20.84% 548.30ms 7984 68.675us 58.977us 81.474us sgemm_sm35_ldg_tn_32x16x64x8x16
Resulted from 7984 calls with (NonTrans, NonTrans) with (m, n, k) = (588, 100, 588)
12.95% 340.71ms 7984 42.674us 21.856us 64.514us sgemm_sm35_ldg_nn_64x16x64x16x16
All the following resulted from 3992 calls with (NonTrans, Trans) with (m, n, k) = (588, 588, 100)
9.81% 258.15ms 3992 64.666us 61.601us 68.642us sgemm_sm35_ldg_nt_128x8x128x16x16
6.84% 179.90ms 3992 45.064us 40.097us 49.505us sgemm_sm35_ldg_nt_64x16x128x8x32
6.33% 166.51ms 3992 41.709us 38.304us 61.185us sgemm_sm35_ldg_nt_128x16x64x16x16另一次运行的588更改为288:
Time(%) Time Calls Avg Min Max Name
--------------------------------------------------------------------------------
Resulted from 7984 calls with (Trans, NonTrans) with (m, n, k) = (288, 100, 288)
22.01% 269.11ms 7984 33.706us 30.273us 39.232us sgemm_sm35_ldg_tn_32x16x64x8x16
Resulted from 7984 calls with (NonTrans, NonTrans) with (m, n, k) = (288, 100, 288)
14.79% 180.78ms 7984 22.642us 18.752us 26.752us sgemm_sm35_ldg_nn_64x16x64x16x16
Resulted from 3992 calls with (NonTrans, Trans) with (m, n, k) = (288, 288, 100)
7.43% 90.886ms 3992 22.766us 19.936us 25.024us sgemm_sm35_ldg_nt_64x16x64x16x16从最后三行看,某些换位类型可能比其他类型更有效,而某些矩阵大小在计算时间上比矩阵大小更经济。确保经济计算的准则是什么?
更新2:
对于(m,n,k) = (588,100,588)的情况,在调用sgemm函数之前,我手动转换了矩阵,那么nvprof结果中只有一个项。所需时间仅略少于上表中这两项的总和。因此,这样做并没有多少性能上的好处。
Time(%) Time Calls Avg Min Max Name
--------------------------------------------------------------------------------
31.65% 810.59ms 15968 50.763us 21.505us 72.098us sgemm_sm35_ldg_nn_64x16x64x16x16发布于 2014-03-01 21:21:53
对不起,我没有回答--但稍微太长了,不能发表评论:
关于编辑,关于“转置”状态的影响:转置矩阵可能会导致访问模式在内存合并方面更糟糕。快速的网络搜索带来了一些关于这一点的结果( https://devtalk.nvidia.com/default/topic/528450/cuda-programming-and-performance/cublas-related-question/post/3734986/#3734986 ),但是与您的设置略有不同:
DGEMM在K20c上的性能 args: ta=N tb=N m=4096 n=4096 k=4096 alpha=-1 beta=2 lda=4096 ldb=4096 ldc=4096 ldb=4096 ldc=4096= 0.13280010秒GFLOPS=1034.93 args: ta=T tb=N m=4096 n=4096 k=4096 alpha=-1 beta=2 lda=4096 ldb=4096 ldc=4096 ldb=4096 ldc=4096= 0.13872910秒GFLOPS=990.7 args: ta=N tb=T m=4096 n=4096 k=4096 alpha=-1 beta=2 lda=4096 ldb=4096 ldc=4096 ldb=4096 ldc=4096= 0.12521601秒GFLOPS=1097.61 args: ta=T tb=T m=4096 n=4096 k=4096 alpha=-1 beta=2 lda=4096 ldb=4096 ldc=4096 ldb=4096 ldc=4096= 0.13652611秒GFLOPS=1006.69
在这种情况下,这些差异似乎不值得更改矩阵存储(例如,从列主到行主,以避免转换矩阵),因为所有模式似乎都以相似的速度运行。但是您的里程可能会有所不同--特别是,(t,n)和(n,n)之间的测试差别非常大(548 vs对340 vs),我发现这是相当令人惊讶的。如果您可以选择在矩阵的各种表示之间轻松切换,那么一个涵盖这四种情况的基准可能是值得的。
无论如何,关于在那里调用的函数的问题: CUBLAS 1.1中的sgemm函数的CUBLAS代码已经满是展开循环,并且已经包含了80 (!)sgemm函数的版本,用于使用#define-hell组装的不同情况。必须假定,在更新的CUBLAS版本中,这变得更加不可读,必须考虑到较新的计算功能--您在那里发现的函数名表明,情况确实如此:
sgemm_sm35_ldg_nt_64x16x128x8x32
sm35:运行在具有计算能力3.5的设备上ldg:?非纹理记忆版本?(CUBLAS1.1包含用于纹理内存的称为sgemm_main_tex_*的函数,以及用于正常全局内存的函数sgemm_main_gld_* )nt:第一个矩阵不是转置的,第二个是转置的64x16x128x8x32 -可能与瓷砖大小、共享内存等有关.不过,我认为对sgemm的单个调用会导致调用这些内部函数中的三个,这是令人惊讶的。但是,正如注释中提到的:我假设他们试图用一个专门的、高效的版本来处理矩阵的“主”部分,并使用能够进行范围检查和/或处理不满的翘曲的“边框”。(不太准确,只是为了暗示:大小为288x288的矩阵可以由大小为256x256的矩阵的有效核心来处理,并对其余的32x288和288x32项进行两个调用)。
但是,这也是为什么我认为矩阵大小几乎不可能有一个一般准则的原因:在计算矩阵大小的时间方面,“最佳”矩阵大小至少将取决于
编辑有关评论:可以想象,应该有一个很大的差异,之间的转基因和非转置处理。当两个矩阵相乘时
a00 a01 a02 b00 b01 b02
a10 a11 a12 * b10 b11 b12
a20 a21 a22 b20 b21 b22那么结果的第一个元素将是
a00 * b00 + a01 * b10 + a02 * b20(它只是a的第一行和b的第一列的点乘积)。对于此计算,必须从a读取连续值。但是从b读取的值不是连续的。相反,它们是“每行中的第一个值”。一个可能认为这会对内存合并产生负面影响。但可以肯定的是,NVIDIA的工程师们已经尽力避免了这里的任何负面影响,而在CUBLAS中实现sgemm与“朴素的3嵌套循环实现的并行版本”相去甚远,因为这种访问模式会有如此明显的缺点。
https://stackoverflow.com/questions/22118822
复制相似问题