【问题标题】:Can I make my compiler use fast-math on a per-function basis?我可以让我的编译器在每个函数的基础上使用快速数学吗?
【发布时间】:2017-04-03 14:27:50
【问题描述】:

假设我有

template <bool UsesFastMath> void foo(float* data, size_t length);

我想用-ffast-math 编译一个实例化(--use-fast-math 用于 nvcc),而另一个实例化没有它。

这可以通过在单独的翻译单元中实例化每个变体来实现,并使用不同的命令行编译每个变体 - 使用和不使用开关。

我的问题是,是否可以向流行的编译器 (*) 指示是否对单个函数应用 -ffast-math - 这样我就可以在同一个翻译单元中进行实例化。

注意事项:

  • 如果答案是“否”,解释为什么不加分。
  • 这与this one 的问题不同,后者是关于在运行时打开和关闭快速数学。我比较谦虚...

(*) 对于流行的编译器,我指的是您拥有这些信息的 gcc、clang、msvc icc、nvcc(用于 GPU 内核代码)中的任何一个。

【问题讨论】:

  • nvcc: 否。编译标志是在每个编译单元的基础上应用的。没有等效的函数属性可以在每个函数的基础上应用它。如果您想应用不同的标志,请将代码粘贴到不同的编译单元中(如果您愿意,可以包含来自同一文件的源代码)。对于严格的本地控制,各种 CUDA 设备内在函数(或者最坏的情况,一些内联汇编)可以提供您需要的大部分内容。
  • 我已按照建议提供了答案

标签: gcc floating-point nvcc fast-math template-instantiation


【解决方案1】:

在 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”这样的拼写错误会被忽略。

【讨论】:

  • "GCC-only feature" - 这只是意味着它不遵循任何公共标准,对吧?还是你也说,比如说clang没有这个功能?
  • 我认为它同时暗示了两者
【解决方案2】:

截至 CUDA 7.5(我熟悉的最新版本,尽管 CUDA 8.0 目前正在发布),nvcc 确实支持允许程序员在每个程序上应用特定编译器优化的函数属性-功能基础。

由于通过命令行开关设置的优化配置适用于整个编译单元,因此一种可能的方法是使用尽可能多的不同编译单元,因为有不同的优化配置,正如问题中已经指出的那样;源代码可以从一个公共文件共享和#include-ed。

使用nvcc,命令行开关--use_fast_math基本上控制三个方面的功能:

  • 已启用清零模式(即禁用非正规支持)
  • 单精度倒数、除法和平方根切换为近似版本
  • 某些标准数学函数已替换为等效的低精度内在函数

您可以通过使用适当的内部函数以按操作粒度应用其中一些更改,其他更改则使用 PTX 内联汇编。

【讨论】:

  • CUDA 8.0 AFAICT 也一样。
猜你喜欢
  • 2017-07-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-22
  • 2021-03-16
  • 1970-01-01
  • 1970-01-01
  • 2022-01-24
相关资源
最近更新 更多