Tag: 编译器优化

GCC -Wuninitialized / -Wmaybe -ininitialized问题

我正在使用gcc-4.7 (Ubuntu/Linaro 4.7.2-11precise2) 4.7.2遇到一个非常奇怪的问题。 我没有警告就无法编译以下有效代码: extern void dostuff(void); int test(int arg1, int arg2) { int ret; if (arg1) ret = arg2 ? 1 : 2; dostuff(); if (arg1) return ret; return 0; } 编译选项和输出: $ gcc-4.7 -o test.o -c -Os test.c -Wall test.c: In function ‘test’: test.c:5:6: warning: ‘ret’ may be used uninitialized in this […]

在编译和链接C代码时,为什么在某些情况下不需要-lm?

我这里有一个示例文件: #include #include int main(){ printf(“%f\n”, log(10)); } 当我用gcc sample.c -oa编译它时它工作得很好。 我可以使用./a运行它,它会产生预期的输出2.302585 。 然而,当我的文件看起来像这样: #include #include int main(){ double a = 10; printf(“%f\n”, log(a)); } 它不能用gcc sample.c -oa编译。 相反,我必须使用gcc sample.c -oa -lm这样我才能显然告诉它“链接数学”…这就是我没有真正遵循的地方,为什么我不必在第一次链接数学例? 它究竟是什么意思必须“链接数学”? 自从我使用C编译器以来已经有一段时间了,所以如果这是一个糟糕的问题,请原谅我。

如何让GCC为没有内置的大端存储生成bswap指令?

我正在研究一个以大端格式将64位值存储到内存中的函数。 我希望我能编写可在小端和大端平台上运行的可移植C99代码,并让现代x86编译器自动生成bswap指令而不需要任何内置函数或内在函数 。 所以我开始使用以下function: #include void encode_bigend_u64(uint64_t value, void *vdest) { uint64_t bigend; uint8_t *bytes = (uint8_t*)&bigend; bytes[0] = value >> 56; bytes[1] = value >> 48; bytes[2] = value >> 40; bytes[3] = value >> 32; bytes[4] = value >> 24; bytes[5] = value >> 16; bytes[6] = value >> 8; bytes[7] = value; […]

multithreading可以抑制编译器优化吗?

我偶然发现有几次将部分程序与OpenMP并行化只是为了注意到最后,尽管具有良好的可扩展性,但由于单线程情况的性能不佳,大多数预见的加速都会丢失(如果与串行版)。 网络上出现的这种行为的常见解释是编译器生成的代码在multithreading情况下可能更糟 。 无论如何,我无法在任何地方找到解释为什么assembly可能更糟的参考。 那么,我想问一下编译器的人是: multithreading可以抑制编译器优化吗? 万一,性能怎么会受到影响? 如果它可以帮助缩小问题,我主要对高性能计算感兴趣。 免责声明 :正如评论中所述,以下部分答案可能在将来过时,因为他们简要讨论了在提出问题时编译器处理优化的方式。

为什么编译器在编译的汇编代码中生成额外的sqrts

我正在尝试使用以下简单的C代码来分析计算sqrt所需的时间,其中readTSC()是一个读取CPU循环计数器的函数。 double sum = 0.0; int i; tm = readTSC(); for ( i = 0; i < n; i++ ) sum += sqrt((double) i); tm = readTSC() – tm; printf("%lld clocks in total\n",tm); printf("%15.6e\n",sum); 但是,当我使用打印出汇编代码时 gcc -S timing.c -o timing.s 在英特尔机器上,结果(如下所示)令人惊讶? 为什么汇编代码中有两个sqrts,一个使用sqrtsd指令而另一个使用函数调用? 它是否与循环展开和尝试在一次迭代中执行两个sqrts相关? 以及如何理解这条线 ucomisd %xmm0, %xmm0 为什么将%xmm0与自身进行比较? //—————-start of for loop—————- call readTSC movq […]

是否有理由不使用链接时优化(LTO)?

GCC,MSVC,LLVM以及可能的其他工具链支持链接时(整个程序)优化,以允许编译单元之间的调用优化。 编译生产软件时是否有理由不启用此选项?

编译器优化导致程序运行速度变慢

我在C中编写了以下代码。它非常简单,因为它恰好为每个for循环移位x 。 int main() { int x = 1; for (int i = 0; i > -2; i++) { x >> 2; } } 现在发生的奇怪的事情是,当我只是编译它而没有任何优化或第一级优化( -O )时,它运行得很好(我正在计时可执行文件和它的大约1.4s -O和5.4s没有任何优化。 现在当我添加-O2或-O3开关进行编译并为生成的可执行文件计时时,它不会停止(我已经测试了多达60s )。 关于可能导致这种情况的任何想法?

为已知的更常见路径优化分支

请考虑以下代码: void error_handling(); bool method_impl(); bool method() { const bool res = method_impl(); if (res == false) { error_handling(); return false; } return true; } 我知道method_impl()将返回true 99.999%(是的,三位小数)的时间,但我的编译器没有。 method()在时间消耗方面是部分关键的。 我应该重写method() (并使其不太可读)以确保只有当method_impl()返回false时才会发生跳转? 如果有,怎么样? 我应该让编译器为我做这项工作吗? 我应该让我的CPU的分支预测为我做的工作吗?

GCC SSE代码优化

这篇文章与我几天前发布的另一篇文章密切相关。 这一次,我编写了一个简单的代码,它只添加了一对元素数组,将结果乘以另一个数组中的值并将其存储在第四个数组中,所有变量浮点数都是双精度类型。 我制作了两个版本的代码:一个是SSE指令,使用调用而另一个没有它我然后用gcc和-O0优化级别编译它们。 我在下面写下: // SSE VERSION #define N 10000 #define NTIMES 100000 #include #include #include #include double a[N] __attribute__((aligned(16))); double b[N] __attribute__((aligned(16))); double c[N] __attribute__((aligned(16))); double r[N] __attribute__((aligned(16))); int main(void){ int i, times; for( times = 0; times < NTIMES; times++ ){ for( i = 0; i <N; i+= 2){ __m128d mm_a = _mm_load_pd( […]

C编译器如何实现返回大型结构的函数?

函数的返回值通常存储在堆栈或寄存器中。 但对于大型结构,它必须在堆栈上。 在这个代码的真实编译器中需要进行多少复制? 还是优化了? 例如: struct Data { unsigned values[256]; }; Data createData() { Data data; // initialize data values… return data; } (假设函数不能内联..)