当使用 icc 编译时,我的程序没有正确 运行
My program does not run properly when compiled with icc
我遇到了 icc 问题,到目前为止我还没有找到任何解决方案。我的程序用gcc编译时运行正常,但用icc编译时显然没有执行任何操作。不会发生运行时错误。该程序结束得非常快(几毫秒),但预计需要几秒钟(n = 10 亿大约需要 11 秒)。但是,如果我在最后打印总数,它就可以了。
这是一个小代码:
# include <stdlib.h>
# include <stdio.h>
double f(double x){
double pi = 3.141592653589793;
double value;
value = 50.0 / (pi * (2500.0 * x * x + 1.0));
return value;
}
int main (int argc, char *argv[]){
double a = 0.0, b = 10.0, total = 0.0, x;
unsigned long int i, n = 1000000000;
for(i = 0; i < n; i++){
x = ((n - i - 1) * a + (i) * b) / (n - 1);
total = total + f(x);
}
total = (b - a) * total / (double) n;
//printf("%f\n", total);
return 0;
}
我还检查了它是否确实运行了循环并调用了函数 n 次。
有谁知道可能导致此问题的原因吗?
谢谢!
However it works okay if I print the total at the end.
这可能是 optimizing compiler effect (legal, per the C11 standard n1570).
由于没有可见side-effect in your program (without the printf
), the compiler is allowed (per the as-if rule)优化成无运行程序
对于 GCC or Clang, and some optimization flags 的某些版本,您可以观察到相同的情况。尝试使用 gcc -O3 -S -fverbose-asm
编译您的代码并查看生成的汇编代码(您将观察到 Linux/x86-64 上使用 GCC 8.1 生成的空 main
)
Does anyone know what could be causing this problem?
您的代码,以及您对 C 的棘手 semantics 的误解。实现的行为符合 C 标准(并且您的程序运行 正确).
顺便说一句,即使使用 printf
,理论上编译器也可以将您的程序优化为一个简单的常量 printf
。实际上,当前的编译器(遗憾的是)没有那么聪明。
如果你想要一些强大的基准,n
可能取决于程序参数(你仍然需要保留 printf
,因为你想要一些可见的副作用)也许:
unsigned long n = (argc<2)?1000:(unsigned long)atol(argv[1]);
测量性能时,不要忘记在编译器中启用优化!
顺便说一句,几年后(在学习了更多的 CS 课程,包括一门关于编译的课程之后,and/or 阅读了 Dragon Book), you might try to implement some GCC plugin which would be able to optimize your function with an explicit printf
(but still n
being initialized to a compile-time constant) into a main
just calling some printf
and doing the loop computing total
at compile-time (such an optimization is legal). You'll discover that making such an optimization takes a lot of work (certainly months, perhaps years!), and might not 适用于许多现有程序的内容,但你可以玩得开心实施它。
如果您对浮点计算感兴趣,请务必阅读floating point guide(这很棘手)。
我遇到了 icc 问题,到目前为止我还没有找到任何解决方案。我的程序用gcc编译时运行正常,但用icc编译时显然没有执行任何操作。不会发生运行时错误。该程序结束得非常快(几毫秒),但预计需要几秒钟(n = 10 亿大约需要 11 秒)。但是,如果我在最后打印总数,它就可以了。
这是一个小代码:
# include <stdlib.h>
# include <stdio.h>
double f(double x){
double pi = 3.141592653589793;
double value;
value = 50.0 / (pi * (2500.0 * x * x + 1.0));
return value;
}
int main (int argc, char *argv[]){
double a = 0.0, b = 10.0, total = 0.0, x;
unsigned long int i, n = 1000000000;
for(i = 0; i < n; i++){
x = ((n - i - 1) * a + (i) * b) / (n - 1);
total = total + f(x);
}
total = (b - a) * total / (double) n;
//printf("%f\n", total);
return 0;
}
我还检查了它是否确实运行了循环并调用了函数 n 次。
有谁知道可能导致此问题的原因吗?
谢谢!
However it works okay if I print the total at the end.
这可能是 optimizing compiler effect (legal, per the C11 standard n1570).
由于没有可见side-effect in your program (without the printf
), the compiler is allowed (per the as-if rule)优化成无运行程序
对于 GCC or Clang, and some optimization flags 的某些版本,您可以观察到相同的情况。尝试使用 gcc -O3 -S -fverbose-asm
编译您的代码并查看生成的汇编代码(您将观察到 Linux/x86-64 上使用 GCC 8.1 生成的空 main
)
Does anyone know what could be causing this problem?
您的代码,以及您对 C 的棘手 semantics 的误解。实现的行为符合 C 标准(并且您的程序运行 正确).
顺便说一句,即使使用 printf
,理论上编译器也可以将您的程序优化为一个简单的常量 printf
。实际上,当前的编译器(遗憾的是)没有那么聪明。
如果你想要一些强大的基准,n
可能取决于程序参数(你仍然需要保留 printf
,因为你想要一些可见的副作用)也许:
unsigned long n = (argc<2)?1000:(unsigned long)atol(argv[1]);
测量性能时,不要忘记在编译器中启用优化!
顺便说一句,几年后(在学习了更多的 CS 课程,包括一门关于编译的课程之后,and/or 阅读了 Dragon Book), you might try to implement some GCC plugin which would be able to optimize your function with an explicit printf
(but still n
being initialized to a compile-time constant) into a main
just calling some printf
and doing the loop computing total
at compile-time (such an optimization is legal). You'll discover that making such an optimization takes a lot of work (certainly months, perhaps years!), and might not 适用于许多现有程序的内容,但你可以玩得开心实施它。
如果您对浮点计算感兴趣,请务必阅读floating point guide(这很棘手)。