2

有没有办法确保:

如果a==b那么devfun(a)==devfun(b);

设备函数在哪里devfun()涉及一些浮点数学运算(例如多项式)并返回浮点结果,a并且b是浮点变量。

我不关心交叉实现的一致性(例如不同的编译器/不同的操作系统/不同的驱动程序版本或不同的编译器选项),我只关心在同一个构建/程序中,在运行时,它能否确保在每个函数调用期间,返回的结果devfun()是一致的,只要a==b, devfun(a)==devfun(b)?

我说的是 SM2.0+ 硬件和 CUDA 5.0+,以防万一。

4

1 回答 1

1

让我们假设您的数字ab表示正确规范化的 IEEE-754 表示浮点数,并且a也不b是一个NaN值。我们还假设ab都是 32 位的,或者a并且b都是 64 位的(IEEE-754 浮点表示)。

在这种情况下,我相信(ISO C/C++ 或 CUDA C/C++)浮点相等性测试(==)将在两个数字ab位相同时返回 TRUE(否则为 FALSE)。

在 TRUE 情况下,除了一个例外,我相信可以安全地假设除了明显的条件之外没有任何其他条件:操作两侧devfun(a) == devfun(b)的行为没有区别,也就是说,它是相同的代码,编译以相同的方式,在相同的条件下执行(例如,可能参与的其他变量、相同的 GPU 类型等),正如您在问题中指出的那样:“相同的建筑/程序”。devfun==devfun

一个例外是如果 的结果devfun(a)NaN, since (IEEE-754) NaN != NaN

如果你认为你有一段代码反驳了这个断言,那会很有趣(对我来说)。

也许浮点忍者会出现并纠正我。

如果我不说浮点比较的危险,也许我也会失职。如果您对此不熟悉(大多数人永远不会a==b建议对两个浮点数进行测试),您可以在 SO 上找到很多关于它的问题。

出于同样的原因,浮点相等比较 ( ==) 通常是不明智的,我认为依赖上述断言,即使它是真的,也是不明智的。让我举一个例子。

假设您为架构编译代码sm_20。现在您在设备上运行代码sm_21。这一简单的变化可能会导致在运行时进行 JIT 编译。现在你不再运行相同的代码,所有的赌注都没有了。

所以,再一次,即使上面是真的,我认为你依赖这样的陈述是不明智的:

if a==b, then devfun(a) == devfun(b)
于 2013-08-11T02:18:32.770 回答