我能否让编译器在逐个函数的基础上使用快速数学计算?

8
假设我有:
template <bool UsesFastMath> void foo(float* data, size_t length);

我希望你能编译一个实例,并使用-ffast-math--use-fast-math用于nvcc)进行优化,另一个实例则不使用。

可以通过在不同的翻译单元中实例化每个变量,并使用不同的命令行参数对它们进行编译来实现此目的。

我的问题是是否有可能向流行的编译器(*)指示对个别函数应用或不应用-ffast-math,以便我能够在同一翻译单元中拥有我的实例。

注意:

  • 如果答案是否定的,说明原因可以获得额外的积分。
  • 这个问题与这个问题不同,后者涉及在运行时开启和关闭快速数学计算。 我比较温和...

(*) 流行的编译器包括:gcc、clang、msvc icc、nvcc(用于GPU内核代码)。


1
nvcc: 每个编译单元都会应用编译标志,没有等效的函数属性可以在每个函数上应用。如果您想要应用不同的标志,请将代码放入不同的编译单元中(如果需要,可以从同一文件中包含源代码)。为了进行紧密的本地控制,各种CUDA设备内部函数(或最坏情况下,一些内联汇编)可以提供您所需的大部分功能。 - njuffa
我已经提供了一个建议的答案。 - njuffa
2个回答

11

在GCC中,你可以这样声明函数:

__attribute__((optimize("-ffast-math")))
double
myfunc(double val)
{
    return val / 2;
}

这是仅适用于GCC的功能。

在此处查看工作示例 -> https://gcc.gnu.org/ml/gcc/2009-10/msg00385.html

似乎GCC不会验证optimize()参数。因此,像“-ffast-match”这样的拼写错误将被默默忽略。


1
“GCC-only feature” - 这只是意味着它不遵循任何公共标准,对吗?或者您是否也在说,例如,clang没有这样的功能? - einpoklum
我认为它同时意味着两者。 - JVApen

4
自CUDA 7.5以来(我熟悉的最新版本,尽管CUDA 8.0目前正在发布),nvcc不支持函数属性,允许程序员按函数应用特定的编译器优化。
由于通过命令行开关设置的优化配置适用于整个编译单元,因此一种可能的方法是使用与不同优化配置相同数量的编译单元,如问题中已经注意到的;源代码可以共享并从公共文件中#include
对于nvcc,命令行开关--use_fast_math基本上控制三个功能区域:
  • 启用Flush-to-zero模式(即禁用非规范化支持)
  • 将单精度倒数、除法和平方根切换为近似版本
  • 某些标准数学函数被等效的低精度内部函数所替换
您可以使用适当的内部函数应用一些这些更改,也可以使用PTX内联汇编应用其他更改。

据我所知,CUDA 8.0也是一样的。 - einpoklum

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接