如何计算内核的Gflops

Fra*_*ter 14 profiling cuda

我想要衡量一下我的内核存档的峰值性能.

假设我有一台NVIDIA Tesla C1060,它的峰值GFLOPS为622.08(〜= 240Cores*1300MHz*2).现在在我的内核中我计算每个线程16000翻牌(4000 x(2减法,1乘法和1 sqrt)).因此,当我有1,000,000个线程时,我会想出16GFLOP.由于内核耗时0.1秒,我将存档160GFLOPS,这将是峰值性能的四分之一.现在我的问题:

  • 这种方法是否正确?
  • 比较(if(a>b) then....)怎么样?我也必须考虑它们吗?
  • 我可以使用CUDA分析器获得更简单,更准确的结果吗?我尝试了instructions计数器,但我无法弄清楚,数字意味着什么.

姐妹问题:如何计算CUDA内核的实现带宽

tal*_*ies 22

首先是一些一般性的评论:

一般来说,你所做的主要是徒劳无功,与大多数人可能会进行绩效分析的方式相反.

要做的第一点是,您引用的峰值严格用于浮点乘加指令(FMAD),它被计为两个FLOPS,并且可以以每个周期一个的最大速率退出.以每个周期一个最大速率退出的其他浮点运算将正式仅被归类为单个FLOP,而其他浮点运算可能需要许多循环才能退役.因此,如果您决定引用针对该峰值的内核性能,您实际上是在将您的代码性能与纯FMAD指令流进行比较,仅此而已.

第二点是,当研究人员从一段代码中引用FLOP/s值时,他们通常使用模型 FLOP计数进行操作,而不是尝试计算指令.矩阵乘法和Linpack LU分解基准是这种性能基准测试方法的典型例子.这些计算的操作计数的下限是完全已知的,因此计算的吞吐量只是下限除以时间.实际的指令数是无关紧要的.程序员经常使用各种技术,包括冗余计算,推测或预测计算,以及许多其他想法,以使代码运行得更快.此类代码的实际FLOP计数是无关紧要的,引用始终是模型FLOP计数.

最后,在考虑量化表现时,通常只有两点比较任何真正的兴趣

  • 代码的版本A在同一硬件上的运行速度是否比版本B快?
  • 硬件A的性能是否比执行感兴趣的任务的硬件B更好?

在第一种情况下,您实际上只需要测量执行时间.在第二种情况下,合适的测量通常不是FLOP/s,它是每单位时间有用的操作(排序中的每秒记录数,流体机械模拟中的每秒单元数等).有时,如上所述,有用的操作可以是已知理论复杂度的操作的模型 FLOP计数.但实际的浮点指令计数很少(如果有的话)进入分析.

如果您真正关心的是优化和理解代码的性能,那么来自NVIDIA的Paulius Micikevicius的演示可能会引起人们的兴趣.

解决要点问题:

这种方法是否正确?

严格来说,没有.如果要计算浮点运算,则需要知道GPU运行代码的确切FLOP计数.例如,该sqrt操作可能比单个FLOP消耗更多,这取决于其实现和它正在操作的数量的特征.编译器还可以执行许多可能会改变实际操作/指令计数的优化.获得真正准确计数的唯一方法是反汇编编译代码并计算各个浮点操作数,甚至可能需要假设代码将计算的值的特征.

比较怎么样(if(a> b)那么......)?我也必须考虑它们吗?

它们不是浮点乘法 - 加法运算,所以没有.

我可以使用CUDA分析器获得更简单,更准确的结果吗?我尝试了指令计数器,但我无法弄清楚,这个数字意味着什么.

并不是的.分析器无法区分浮点指令和任何其他类型的指令,因此(截至2011年)无法通过分析器从一段代码中进行FLOP计数.[编辑:请参阅下面的Greg的优秀答案,讨论自该答案撰写以来发布的分析工具版本中可用的FLOP计数设施]


Gre*_*ith 11

Nsight VSE(> 3.2)和Visual Profiler(> = 5.5)支持已实现的FLOP计算.为了收集度量标准,分析器运行内核两次(使用内核重放).在第一次重放中,收集执行的浮点指令的数量(了解预测和活动掩码).在第二次重播中,收集持续时间.

nvprof和Visual Profiler具有硬编码定义.FMA计为2次操作.所有其他操作都是1次操作.flops_sp_*计数器是线程指令执行计数,而flops_sp是加权和,因此可以使用各个度量来应用一些加权.但是,flops_sp_special涵盖了许多不同的指令.

Nsight VSE实验配置允许用户定义每个指令类型的操作.

Nsight Visual Studio Edition

配置以收集已实现的FLOPS

  1. 执行菜单命令Nsight> Start Performance Analysis ...以打开Activity Editor
  2. 活动类型设置为配置文件CUDA应用程序
  3. 在实验设置中将实验设置为运行自定义
  4. 在实验列表中添加Achieved FLOPS
  5. 在中间窗格中,选择Achieved FLOPS
  6. 在右侧窗格中,您可以按执行的每条指令自定义FLOPS.默认加权是FMA和RSQ计为2.在某些情况下,我看到RSQ高达5.
  7. 运行分析会话.

Nsight VSE实现了FLOPS实验配置

查看已实现的FLOPS

  1. 在nvreport中打开CUDA Launches报告页面.
  2. CUDA Launches页面中选择一个内核.
  3. 在报告关联窗格(左下角)中,选择已实现的FLOPS

Nsight VSE实现了FLOPS结果

nvprof

可用指标(在K20上)

nvprof --query-metrics | grep flop
flops_sp:            Number of single-precision floating-point operations executed by non-predicated threads (add, multiply, multiply-accumulate and special)
flops_sp_add:        Number of single-precision floating-point add operations executed by non-predicated threads
flops_sp_mul:        Number of single-precision floating-point multiply operations executed by non-predicated threads
flops_sp_fma:        Number of single-precision floating-point multiply-accumulate operations executed by non-predicated threads
flops_dp:            Number of double-precision floating-point operations executed non-predicated threads (add, multiply, multiply-accumulate and special)
flops_dp_add:        Number of double-precision floating-point add operations executed by non-predicated threads
flops_dp_mul:        Number of double-precision floating-point multiply operations executed by non-predicated threads
flops_dp_fma:        Number of double-precision floating-point multiply-accumulate operations executed by non-predicated threads
flops_sp_special:    Number of single-precision floating-point special operations executed by non-predicated threads
flop_sp_efficiency:  Ratio of achieved to peak single-precision floating-point operations
flop_dp_efficiency:  Ratio of achieved to peak double-precision floating-point operations
Run Code Online (Sandbox Code Playgroud)

收集和结果

nvprof --devices 0 --metrics flops_sp --metrics flops_sp_add --metrics flops_sp_mul --metrics flops_sp_fma matrixMul.exe
[Matrix Multiply Using CUDA] - Starting...
==2452== NVPROF is profiling process 2452, command: matrixMul.exe
GPU Device 0: "Tesla K20c" with compute capability 3.5

MatrixA(320,320), MatrixB(640,320)
Computing result using CUDA Kernel...
done
Performance= 6.18 GFlop/s, Time= 21.196 msec, Size= 131072000 Ops, WorkgroupSize= 1024 threads/block
Checking computed result for correctness: OK

Note: For peak performance, please refer to the matrixMulCUBLAS example.
==2452== Profiling application: matrixMul.exe
==2452== Profiling result:
==2452== Metric result:
Invocations                               Metric Name                        Metric Description         Min         Max         Avg
Device "Tesla K20c (0)"
        Kernel: void matrixMulCUDA<int=32>(float*, float*, float*, int, int)
        301                                  flops_sp                             FLOPS(Single)   131072000   131072000   131072000
        301                              flops_sp_add                         FLOPS(Single Add)           0           0           0
        301                              flops_sp_mul                         FLOPS(Single Mul)           0           0           0
        301                              flops_sp_fma                         FLOPS(Single FMA)    65536000    65536000    65536000
Run Code Online (Sandbox Code Playgroud)

注意:flops_sp = flops_sp_add + flops_sp_mul + flops_sp_special +(2*flops_sp_fma)(大约)

Visual Profiler

Visual Profiler支持上面nvprof部分中显示的指标.

  • 为了我的理解。你说:_nvprof 和 Visual Profiler 有一个硬编码的定义。FMA 算作“2”操作;所有其他操作都是“1”操作_。因此,如果您有超越函数(例如“exp()”、“sin()”等)和特殊函数(例如“bessel”函数(在 CUDA 提供的版本中))的组合,分析器如何估计数量操作计数,这似乎是@talonmies 提出的主要问题之一? (2认同)