我想要衡量我的内核归档的最高性能。
假设我有一台NVIDIA Tesla C1060,它具有peak GFLOPS of 622.08(〜= 240Cores * 1300MHz * 2)。
现在在我的内核中,我为每个线程计算了16000 flop(4000 x(2减,1乘和1 sqrt))。因此,当我有1,000,000个线程时,我将使用16GFLOP。而且由于内核需要0.1秒,所以我将存档160GFLOPS,这将是峰值性能的四分之一。现在我的问题是:

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

姊妹问题:How to calculate the achieved bandwidth of a CUDA kernel

最佳答案

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

总的来说,您所做的主要是徒劳无益的练习,并且与大多数人可能进行性能分析的方式相反。

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

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

最后,在评估效果时,通常只有两点可以与任何实际兴趣进行比较


在相同的硬件上,代码的A版本是否比B版本运行得更快?
硬件A在执行目标任务方面是否比硬件B更好?


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

如果您真的对优化和理解代码的性能感兴趣,那么也许来自NVIDIA的Paulius Micikevicius的this presentation可能会引起您的兴趣。

解决要点问题:


这种方法正确吗?


严格来说,不是。如果要计算浮点运算,则需要从GPU运行的代码中知道确切的FLOP计数。例如,sqrt操作可能比单个FLOP消耗更多的电量,具体取决于它的实现方式和所要操作的数字的特性。编译器还可以执行很多优化,这可能会更改实际的操作/指令计数。获得真正准确计数的唯一方法是反汇编已编译的代码并对单个浮点操作数进行计数,甚至可能需要假设有关代码将计算的值的特征。


那么比较(如果(a> b)...)呢?我也必须考虑它们吗?


它们不是浮点乘法加法运算,所以不行。


我可以使用CUDA分析器来获得更简单,更准确的结果吗?我尝试了指令计数器,但我不知道该数字是什么意思。


并不是的。探查器无法区分浮点指令和任何其他类型的指令,因此(自2011年起)无法通过探查器从一段代码中进行FLOP计数。 [编辑:请参阅下面的Greg出色答案,以讨论自撰写此答案以来发布的概要分析工具版本中可用的FLOP计数功能。

关于profiling - 如何计算内核的Gflops,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7875607/

10-10 19:01