Tag: 编译器优化

为什么Haskell中没有隐含的并行性?

Haskell是function性和纯粹的,所以基本上它具有编译器能够处理隐式并行所需的所有属性。 考虑这个微不足道的例子: f = do a <- Just 1 b <- Just $ Just 2 — ^ The above line does not utilize an `a` variable, so it can be safely — executed in parallel with the preceding line c <- b — ^ The above line references a `b` variable, so it can only […]

为什么gcc允许从结构中投机加载?

显示可能会出错的gcc优化和用户代码示例 下面代码片段中的函数“foo”只会加载其中一个结构成员A或B; 至less这是未经优化的代码的意图。 typedef struct { int A; int B; } Pair; int foo(const Pair *P, int c) { int x; if (c) x = P->A; else x = P->B; return c/102 + x; } 以下是gcc -O3给出的内容: mov eax, esi mov edx, -1600085855 test esi, esi mov ecx, DWORD PTR [rdi+4] <– ***load P->B** cmovne […]

如何closuresgcc编译器优化来启用缓冲区溢出

我正在做一个家庭作业问题 ,需要禁用编译器优化保护才能正常工作。 我在Ubuntu的Linux上使用gcc 4.4.1,但不知道哪个标志是正确的。 我意识到这是依赖于架构 – 我的机器运行W / 32位英特尔处理器。 谢谢。

/ Ox和/ O2编译器选项有什么区别?

微软的C ++编译器(包含在Visual Studio中的cl.exe )提供了几个优化开关 。 大多数的区别似乎是不言自明的,但是我不清楚/O2 (哪个优化代码为最大速度)和/Ox (哪个select“全优化”)之间的区别。 我已经尝试阅读/Ox选项的文档 ,并且似乎证实了这个开关还能够优化最大速度,而不是大小: /Ox编译器选项产生的代码优先于较小的执行速度。 但是,特别是“备注”部分下面的陈述引起了我的注意: 通常,指定/O2 (最大化速度)而不是/Ox 。 所以我的问题是, 为什么一个人应该普遍支持/O2 /Ox ? 后面的选项是否使已知的特定优化导致不可预见的错误或其他意外的行为? 简单地说,获得的优化量不值得额外的编译时间吗? 或者,这只是一个完全没有意义的“推荐”,因为/O2是VS中的默认选项?

当永远不会执行的代码被注释掉时,Java程序会运行得更慢

我在其中一个Java程序中观察到一些奇怪的行为。 我试图尽可能地去除代码,同时仍然能够复制行为。 代码全部在下面。 public class StrangeBehaviour { static boolean recursionFlag = true; public static void main(String[] args) { long startTime = System.nanoTime(); for (int i = 0; i < 10000; i ++) { functionA(6, 0); } long endTime = System.nanoTime(); System.out.format("%.2f seconds elapsed.\n", (endTime – startTime) / 1000.0 / 1000 / 1000); } static boolean […]

编译器优化能否引入错误?

今天我和我的一个朋友进行了一次讨论,我们就“编译器优化”问题进行了几个小时的讨论。 我曾经辩解过, 有时编译器优化可能会引入错误或者至less是不希望的行为。 我的朋友完全不同意,说“编译器是聪明人做的,做聪明的事情”,所以不会出错。 他根本没有说服我,但我不得不承认我缺乏现实的例子来强化我的观点。 谁在这里? 如果是,那么你是否有一个真实的例子,编译器优化在结果软件中产生了一个bug? 如果我错了,我应该停止编程,学习捕鱼吗?

GCC如何优化一个在循环内部递增的未使用的variables?

我写了这个简单的C程序: int main() { int i; int count = 0; for(i = 0; i < 2000000000; i++){ count = count + 1; } } 我想看看gcc编译器如何优化这个循环(显然加120亿次应该是“新增20亿次”)。 所以: gcc test.c然后在a.out给出: real 0m7.717s user 0m7.710s sys 0m0.000s $ gcc -O2 test.c然后time on a.out time on执行time on : real 0m0.003s user 0m0.000s sys 0m0.000s 然后我用gcc -S拆卸了两个。 第一个看起来很清楚: .file "test.c" […]

为什么GCC不能优化“x &&(x&4242)”到“x&4242”的逻辑按位AND对?

这里有两个function,我声称做同样的事情: bool fast(int x) { return x & 4242; } bool slow(int x) { return x && (x & 4242); } 从逻辑上说,他们做同样的事情,只是为了100%肯定我写了一个testing,通过他们两个跑了所有40亿可能的投入,他们匹配。 但汇编代码是一个不同的故事: fast: andl $4242, %edi setne %al ret slow: xorl %eax, %eax testl %edi, %edi je .L3 andl $4242, %edi setne %al .L3: rep ret 我感到惊讶的是,海合会无法跨越逻辑消除冗余testing。 我用-O2,-O3和-Os尝试了g ++ 4.4.3和4.7.2,所有这些都生成了相同的代码。 该平台是Linux x86_64。 有人可以解释为什么海湾合作委员会不应该足够聪明,在这两种情况下生成相同的代码? 我也想知道其他编译器是否可以做得更好。 […]

德摩根定律与重载操作符的优化

每个程序员都应该知道: ( 德摩根定律) 在某些情况下,为了优化程序,可能会发生编译器将(!p && !q)修改为(!(p || q)) 。 这两个expression式是等价的,对第一个和第二个expression式没有任何区别。 但是在C ++中,可能会重载操作符,重载操作符可能并不总是尊重这个属性。 所以这样转换代码实际上会修改代码。 如果编译器使用De Morgan's Laws ! , || 和&&超载?

为什么memcmp(a,b,4)只是有时被优化为uint32比较?

鉴于此代码: #include <string.h> int equal4(const char* a, const char* b) { return memcmp(a, b, 4) == 0; } int less4(const char* a, const char* b) { return memcmp(a, b, 4) < 0; } x86_64上的GCC 7引入了对第一种情况的优化(Clang已经做了很长一段时间): mov eax, DWORD PTR [rsi] cmp DWORD PTR [rdi], eax sete al movzx eax, al 但第二种情况仍然调用memcmp() : sub rsp, 8 […]