我想要衡量一下我的内核存档的峰值性能有多少。
假设我有一台NVIDIA Tesla C1060,其peak GFLOPS of 622.08(〜= 240Cores * 1300MHz * 2)。 现在在我的内核中我计算每个线程16000翻牌(4000 x(2减法,1乘法和1 sqrt))。因此,当我有1,000,000个线程时,我会想出16GFLOP。由于内核耗时0.1秒,我将存档160GFLOPS,这将是峰值性能的四分之一。现在我的问题:
if(a>b) then....
)怎么样?我是否也必须考虑它们?instructions
计数器,但我无法弄清楚,这个数字意味着什么。答案 0 :(得分:21)
首先是一些一般性评论:
一般来说,你所做的主要是徒劳无功,与大多数人可能会进行绩效分析的方式相反。
要做的第一点是,您引用的峰值严格用于浮点乘法加法指令(FMAD),它被计为两个FLOPS,并且可以以每个周期一个的最大速率退出。以每个周期一个最大速率退出的其他浮点运算将正式仅被归类为单个FLOP,而其他浮点运算可能需要许多循环才能退役。因此,如果您决定引用针对该峰值的内核性能,您实际上是在将您的代码性能与纯FMAD指令流进行比较,仅此而已。
第二点是,当研究人员从一段代码中引用FLOP / s值时,他们通常使用模型 FLOP计数进行操作,而不是尝试计算指令。矩阵乘法和Linpack LU分解基准是这种性能基准测试方法的典型例子。这些计算的操作计数的下限是完全已知的,因此计算的吞吐量只是下限除以时间。实际的指令数是无关紧要的。程序员经常使用各种技术,包括冗余计算,推测或预测计算,以及许多其他想法,以使代码运行得更快。此类代码的实际FLOP计数是无关紧要的,引用始终是模型FLOP计数。
最后,在考虑量化表现时,通常只有两点比较任何真正的兴趣
在第一种情况下,您实际上只需要测量执行时间。在第二种情况下,合适的测量通常不是FLOP / s,它是每单位时间有用的操作(排序中的每秒记录数,流体机械模拟中的每秒单元数等)。有时,如上所述,有用的操作可以是已知理论复杂度的操作的模型 FLOP计数。但实际的浮点指令计数很少(如果有的话)进入分析。
如果您真的想要优化并了解代码的性能,那么来自NVIDIA的Paulius Micikevicius可能感兴趣this presentation。
解决要点问题:
这种做法是否正确?
严格来说,没有。如果要计算浮点运算,则需要知道GPU运行代码的确切FLOP计数。例如,sqrt
操作可能比单个FLOP消耗更多,具体取决于其实现和操作数量的特征。编译器还可以执行许多可能会改变实际操作/指令计数的优化。获得真正准确计数的唯一方法是反汇编编译代码并计算单个浮点操作数,甚至可能需要假设代码将计算的值的特征。
比较怎么样(if(a> b)那么....)?我是否也必须考虑它们?
它们不是浮点乘法 - 加法运算,所以没有。
我可以使用CUDA分析器获得更简单,更准确的结果吗?我尝试了指令计数器,但我无法弄清楚,数字意味着什么。
不是真的。分析器无法区分浮点指令和任何其他类型的指令,因此(截至2011年)无法通过分析器从一段代码中进行FLOP计数。 [编辑:请参阅以下Greg的优秀答案,讨论自该答案撰写以来发布的分析工具版本中可用的FLOP计数工具]
答案 1 :(得分:10)
Nsight VSE(> 3.2)和Visual Profiler(> = 5.5)支持已实现的FLOP计算。为了收集度量标准,分析器运行内核两次(使用内核重放)。在第一次重放中,收集执行的浮点指令的数量(了解预测和活动掩码)。在第二次重播中收集持续时间。
nvprof和Visual Profiler具有硬编码定义。 FMA计为2次操作。所有其他操作都是1次操作。 flops_sp_ *计数器是线程指令执行计数,而flops_sp是加权和,因此可以使用各个度量来应用一些加权。但是,flops_sp_special涵盖了许多不同的指令。
Nsight VSE实验配置允许用户定义每种指令类型的操作。
配置收集已实现的FLOPS
查看已实现的FLOPS
可用指标(在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
收集和结果
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
注意:flops_sp = flops_sp_add + flops_sp_mul + flops_sp_special +(2 * flops_sp_fma)(约)
Visual Profiler支持上面nvprof部分中显示的指标。