我正在尝试了解GPU的体系结构以及我们如何评估GPU上程序性能的方法。我知道该应用程序可以是:
内存受限:性能受内存限制 带宽。处理器的核心经常处于空闲状态,因为内存无法足够快地提供数据
下图显示了每个微体系结构的FLOPS速率,峰值内存带宽和所需的计算与内存之比,用(OP / B)标记。
我也有一个如何计算此OP / B指标的示例。示例:以下是用于应用矩阵矩阵乘法的CUDA代码的一部分
for(unsigned int i = 0; i < N; ++i) {
sum += A[row*N + i]*B[i*N + col];
}
以及用于此矩阵矩阵乘法的OP / B的计算方法如下:
,如果我们想利用它:
因此,如果我清楚地理解了这一点,那么我会提出以下问题:
答案 0 :(得分:2)
通常情况下,OP / B越大越好?
并非总是如此。目标值平衡了计算管道吞吐量和内存管道吞吐量的负载(即,操作/字节级别意味着两个管道都将被完全加载)。当您将操作/字节增加到该水平或某个级别以上时,您的代码将从平衡状态切换到计算范围。一旦您的代码受计算限制,性能将由作为限制因素的计算管道决定。超出此点,额外的操作/字节增加可能不会影响代码性能。
我们如何知道我们有多少FP操作?是加法还是乘法
是的,对于您显示的简单代码,它是加法和乘法。其他更复杂的代码可能还具有其他因素(例如sin
,cos
等)。
除了“手动计数” FP操作之外,GPU分析器还可以指示代码已执行的FP op的数量。
我们如何知道每个FP操作加载了多少字节?
类似于上一个问题,对于简单的代码,您可以“手动计数”。对于复杂的代码,您可能希望尝试使用探查器功能进行估算。对于您显示的代码:
sum += A[row*N + i]*B[i*N + col];
必须加载A
和B
中的值。如果它们是float
个数量,则每个为4个字节。总共8个字节。该行代码将需要1个浮点乘法(A * B)和1个浮点加法运算(sum + =)。编译器会将它们融合为一条指令(融合的乘法加法),但最终结果是您每8个字节执行两个浮点运算。操作/字节为2/8 = 1/4。在这种情况下,循环不会更改比率。要增加此数量,您需要探索各种优化方法,例如a tiled shared-memory matrix multiply,或仅使用CUBLAS。
(row*N + i
之类的操作是整数算术,虽然对性能而言可能是重要的,但对浮点负载没有帮助。)