如何让 CC 2.0 和 3.0 编译器生成 FMA 指令?
Posted
技术标签:
【中文标题】如何让 CC 2.0 和 3.0 编译器生成 FMA 指令?【英文标题】:How do I get the CC 2.0 and 3.0 compilers to generate FMA instructions? 【发布时间】:2013-02-10 00:57:41 【问题描述】:我正在尝试通过生成一系列 FMA 指令来运行性能测试。但是,我似乎无法让 CC 2.0 和 CC 3.0 编译器生成 FMA 指令。
如果我编译:
for (float x = 0; x < loop; x++)
a += x * loop;
a += x * loop;
... (6 more repetitions)
其中loop
也是一个浮点数,对于a += x * loop;
的每一行,我得到以下内容:
compute_10,sm_10:
a += x * loop;
0x0001ffa0 [0103] mov.f32 %f11, %f2;
0x0001ffa0 MOV R3, R2;
0x0001ffa8 [0104] ld.param.f32 %f12, [__cudaparm__Z6kernelPfifS__loop];
0x0001ffa8 MOV32I R2, 0x28;
0x0001ffb0 LDC R2, c[0x0][R2];
0x0001ffb8 [0105] mov.f32 %f13, %f4;
0x0001ffb8 MOV R0, R0;
0x0001ffc0 [0106] mad.f32 %f14, %f12, %f13, %f11;
0x0001ffc0 FFMA.FTZ R2, R2, R0, R3;
0x0001ffc8 [0107] mov.f32 %f2, %f14;
0x0001ffc8 MOV R2, R2;
compute_30,sm_30:
a += x * loop;
0x00044688 [0101] mul.f32 %f14, %f30, %f7;
0x00044688 FMUL R5, R4, R0;
0x00044690 [0102] add.f32 %f15, %f13, %f14;
0x00044690 FADD R3, R3, R5;
也就是说,在为 CC 3.0 编译时,我得到的是 FMUL/FADD 指令而不是 FFMA。为 CC 1.0 编译时,我得到一条 FFMA 指令。
我也在带有compute_20,sm_20
的 CC 2.0 编译器以及发布和调试版本中获得此结果。
我尝试指定-use_fast_math
和--fmad=true
。我使用 CUDA 4.2 和 5.0 向导创建了项目,并且没有更改默认设置。
环境:
Windows 7 64 位 Visual Studio 2010 CUDA 4.2 + CUDA 5.0(5.0 安装在 4.2 之上) GPU:单 GTX660 Nsight 3.0 RC1和
Windows 7 64 位 Visual Studio 2010 CUDA 4.2 Nsight 2.2 GPU:单 GTX570【问题讨论】:
loop
的值是多少?
@Mikhail: loop
是一个浮点内核参数。我一直在传递一个 100.0f 的值。
我使用 cuda 5.0 和一个非常简单的内核在 cc2.0 上生成 fma 指令没有问题。也许您可以发布一个完整的、可编译的示例。这是我所做的an example,尽管是在 linux 上。
我想知道这是否是获得最佳性能的正确选择。请参阅此主题:***.com/questions/12011708/…。
@RobertCrovella:我为 CC 2.0 编译了您的示例,并且仍然为每个 c += a * a;
获得了一个 FMUL/FADD 对。
【参考方案1】:
将-G
开关传递给 nvcc 会影响代码生成,还会生成要添加到输出文件的附加调试信息(符号)。根据nvcc documentation,-G
开关的描述不是“生成设备调试信息”,而是“生成可调试设备代码”。
在许多情况下,使用 -G 开关会导致设备代码生成大不相同。在这种情况下,它似乎抑制了 FMA 指令的生成,而支持单独的 MUL/ADD 序列。
【讨论】:
我为此提交了一份低优先级的错误报告,因为 Nsight for Visual Studio 中的开关描述仅显示“生成 GPU 调试信息”和“指定 GPU 调试信息是否由CUDA 编译器”。以上是关于如何让 CC 2.0 和 3.0 编译器生成 FMA 指令?的主要内容,如果未能解决你的问题,请参考以下文章
如何让 JWT 在 Autorest 生成的 SDK 中工作? (ASP.NET 核心 2.0)