我有祸了,我必须在GPU和CPU上确保相同的浮点结果。好的,我理解IEEE已经照顾好我并提供了一个很好的标准来坚持几个舍入选项;并且CUDA部分被整理出来(有不同舍入模式的内在函数),所以这只是动机。
但是在主机端C ++代码中 - 如何在特定的舍入模式下执行浮点运算(我的意思是在特定的语句中,而不是在我的翻译单元中)?是否有使用引擎盖组件的包装功能?是否有一组具有不同舍入模式的浮点数代理类?
我也在询问有关翻译单元级别的相同问题。在编译翻译单元时,如何使编译器(gcc / clang / MSVC)默认为某种舍入模式?
答案 0 :(得分:0)
在@AndreasPapadopoulos的带领下,看起来像there is an official way更改了舍入模式:
int fesetround(int round)
int fegetround()
但有几点需要注意:
<fenv.h>
C99。#pragma
的我不确定它在实践中的使用范围有多广(以及周围是否有更好的抽象,更常见的用途)。
答案 1 :(得分:0)
一种简单的处理方法是引入一个类,该类在初始化时设置舍入模式,并在超出范围时将其重置为先前的模式,如下所示:
#include <cfenv>
//Simple class to enable directed rounding in floating-point math and to reset
//the rounding mode afterwards, when it goes out of scope
struct SetRoundingMode {
const int old_rounding_mode;
SetRoundingMode(const int mode) : old_rounding_mode(fegetround()) {
if(std::fesetround(mode)!=0){
throw std::runtime_error("Failed to set directed rounding mode!");
}
}
~SetRoundingMode(){
// More recent versions of C++ don't like exceptions in the destructor
// so you may need a different way of handling issues here.
if(std::fesetround(old_rounding_mode)!=0){
throw std::runtime_error("Failed to reset rounding mode to original value!");
}
}
static std::string get_rounding_mode_string() {
switch (fegetround()) {
case FE_DOWNWARD: return "downward";
case FE_TONEAREST: return "to-nearest";
case FE_TOWARDZERO: return "toward-zero";
case FE_UPWARD: return "upward";
default: return "unknown";
}
}
};
然后你可以像这样使用
void foo(){
const auto srm = SetRoundingMode(FE_UPWARD);
}
请注意,所有舍入模式都列在类中。