这是我对dot产品的天真实现:
float simple_dot(int N, float *A, float *B) {
float dot = 0;
for(int i = 0; i < N; ++i) {
dot += A[i] * B[i];
}
return dot;
}
Run Code Online (Sandbox Code Playgroud)
这是使用C++库:
float library_dot(int N, float *A, float *B) {
return std::inner_product(A, A+N, B, 0);
}
Run Code Online (Sandbox Code Playgroud)
我运行了一些基准测试(代码在这里https://github.com/ijklr/sse),库版本慢很多.我的编译器标志是-Ofast -march=native
当将 exe 复制到另一台计算机(具有 2022 Intel 处理器)时,在一台 Windows 计算机中使用 Visual Studio 2019 在 2018 Intel 处理器上编译的 Fortran 代码是否可能会产生稍微不同的结果?您能否列出导致此行为的可能原因?
让我们考虑一个简单的简化,例如点积:
pub fn add(a:&[f32], b:&[f32]) -> f32 {
a.iter().zip(b.iter()).fold(0.0, |c,(x,y)| c+x*y))
}
Run Code Online (Sandbox Code Playgroud)
使用 rustc 1.68 与-C opt-level=3 -C target-feature=+avx2,+fma
我得到
.LBB0_5:
vmovss xmm1, dword ptr [rdi + 4*rsi]
vmulss xmm1, xmm1, dword ptr [rdx + 4*rsi]
vmovss xmm2, dword ptr [rdi + 4*rsi + 4]
vaddss xmm0, xmm0, xmm1
vmulss xmm1, xmm2, dword ptr [rdx + 4*rsi + 4]
vaddss xmm0, xmm0, xmm1
vmovss xmm1, dword ptr [rdi + 4*rsi + 8]
vmulss xmm1, xmm1, dword ptr [rdx + …
Run Code Online (Sandbox Code Playgroud) 我在使用GCC for ARM时出现了一个非常奇怪的问题,并且启用了优化.在没有优化的情况下编译我的C++应用程序会生成一个可执行文件,在运行时输出预期的结果.一旦我打开优化 - 即-O1 - 我的应用程序就无法产生预期的结果.我试了几天才发现问题,但我很无能为力.我从我的代码中删除了任何未初始化的变量,我纠正了严格混叠可能导致问题但仍然没有正确结果的位置.
我正在使用GCC 4.2.0 for ARM(处理器是ARM926ej-s)并在Montavista Linux发行版上运行该应用程序.
以下是我正在使用的标志:
-O1 -fno-unroll-loops fno-merge-constants -fno-omit-frame-pointer -fno-toplevel-reorder \
-fno-defer-pop -fno-function-cse -Wuninitialized -Wstrict-aliasing=3 -Wstrict-overflow=3 \
-fsigned-char -march=armv5te -mtune=arm926ej-s -ffast-math
Run Code Online (Sandbox Code Playgroud)
一旦我剥离-O1标志并重新编译/重新链接应用程序,我就会得到正确的输出结果.正如你从旗帜中看到我试图禁用任何优化我认为它可能会导致问题,但仍然没有运气.
有没有人对如何进一步解决这个问题有任何指示?
谢谢
我正在使用以下-ffast-math
选项编译以下代码:
#include <limits>
#include <cmath>
#include <iostream>
int main() {
std::cout << std::isnan(std::numeric_limits<double>::quiet_NaN() ) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
我输出0.在编译时,我的代码如何判断浮点数是否为NaN -ffast-math
?
注意:在linux上,std :: isnan甚至可以使用-ffast-math.
以下 3 行使用"gcc -Ofast -march=skylake"给出不精确的结果:
int32_t i = -5;
const double sqr_N_min_1 = (double)i * i;
1. - ((double)i * i) / sqr_N_min_1
Run Code Online (Sandbox Code Playgroud)
显然,第三行中的sqr_N_min_1
gets25.
和(-5 * -5) / 25
应该变为 ,1.
因此第三行的整体结果正好是0.
。事实上,这对于编译器选项"gcc -O3 -march=skylake"是正确的。
但是使用“-Ofast”,最后一行产生-2.081668e-17
而不是0.
和i
除了-5
(例如6
或7
)之外的其他非常小的正或负随机偏差0.
。我的问题是:这种不精确的根源究竟在哪里?
为了调查这个,我用 C 写了一个小测试程序:
#include <stdint.h> /* int32_t */
#include <stdio.h>
#define MAX_SIZE 10
double W[MAX_SIZE];
int main( …
Run Code Online (Sandbox Code Playgroud) 最近我遇到了一个关于 LTO 的奇怪问题,根据是否使用,-ffast-math
我的“pow”(in)调用得到了不一致的结果。cmath
-flto
$ g++ --version
g++ (GCC) 8.3.0
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ ll /lib64/libc.so.6
lrwxrwxrwx 1 root root 12 Sep 3 2019 /lib64/libc.so.6 -> libc-2.17.so
$ ll /lib64/libm.so.6
lrwxrwxrwx 1 root root 12 Sep 3 2019 /lib64/libm.so.6 -> libm-2.17.so
$ cat /etc/redhat-release
CentOS Linux release …
Run Code Online (Sandbox Code Playgroud) 任何人都可以帮助我理解使用gcc编译时-ffast-math选项的作用.使用-O3和-ffast-math执行时,我看到程序执行时间相差20秒,而只使用-O3