我有一些遗留代码,其中包含一个浪费时间的循环,以便有时间完成eeprom读取(不好的做法):
for(i = 0; i < 50; i++);
但是,当为了提高速度而打开编译器优化时,会发生一些奇怪的事情。它不一定与该语句相关联,但我想知道编译器是否可能只是优化了时间延迟
伦丁的回答解释了为什么它会发生,所以不需要解释。
也就是说,如果您真的需要在循环中保持旧的行为,但优化其余的行为,最简单的方法是将这个活动延迟循环放在一个文件中的一个函数中:
#include <active_delay.h> // the corresponding header file
void active_delay(int d)
{
// do not build with optimize flags on!
int i;
for(i = 0; i < d; i++);
}
并在没有任何优化标志的情况下构建这个文件。
使用优化标志构建代码的其余部分,以便从“正常”代码上的优化器中受益。
注意,由于函数调用开销和循环的执行时间很短,当从内联调用移动到单独的对象文件中的函数时,延迟会略微增加。
您可能希望减少d
值以匹配之前的计时(如果需要)
这取决于i
的类型。如果它只是一个普通的整数类型,除了在循环内部之外没有使用,那么没有副作用,编译器可以自由地优化整个事情。
但是,如果将< code>i声明为< code>volatile,编译器将被迫生成代码,在循环的每一圈递增变量并读取它。
这就是为什么你不应该在嵌入式系统中使用像这样的“一次性”循环的原因之一。你也占用100%的CPU,消耗100%的电流。并且在系统时钟和环路之间建立了紧密耦合,这不一定是线性的。
专业解决方案始终是使用片上硬件定时器,而不是“烧掉”环路。
我在godbolt上编译这段代码。orgwith-O2和编译器不会使用一些memcpy对其进行优化,而是诚实地运行循环。 但是,如果我将“= src[i]”替换为“= 0”,他们会使用memset。但同样,当我用“ = 1”替换它时,它们会运行一个循环。当要设置的值不为零时,为什么它们会避免使用 memcpy 和 memset?我认为这是他们将执行的第一批优化之一。
本文向大家介绍C/C++ 编译器优化介绍,包括了C/C++ 编译器优化介绍的使用技巧和注意事项,需要的朋友参考一下 0. gcc -o gcc -o 的优化仍然是机械的,想当然的。只有做到深入理解计算机系统,加深对编程语言的理解,才能写出最优化的代码。 Linux下gcc 优化级别的介绍 · gcc -o0 ⇒ 不提供任何优化; · gcc -o1 ⇒ 最基本的优化,主要对代码的分支、表达式、
问题内容: 我正在编写一个常量字符串比较函数(用于node.js),并且想为此功能禁用V8的优化编译器;使用命令行标志是不可能的。 我知道,使用(或try / catch语句)块将禁用优化编译器 现在 ,但恐怕这个“功能”(错误)将被固定在未来的版本。 是否有一种不可变(且已记录)的方式来禁用V8的优化编译器? 示例功能: 性能测试只是为了好玩。 问题答案: 如果您想要可靠的方法来执行此操作,则需
在 C 或 C 中,如果编译器遇到一个 循环,其中计数器从 计数到 n, n 是一个变量(不是函数调用,也不是常量),编译器是否会通过检查变量 (绑定变量)是否会在循环期间更改(访问写入, 例如: 可以是循环前计算的字符串的长度),通过优化这里,我的意思是将其值复制到寄存器以避免内存访问? 下面是一个示例: 编译器会注意到这一点并对其进行优化吗?
问题内容: 我一直在尝试在我的EC2实例上安装Gearman,但是当我尝试./configure gearmand时,我得到了: 现在,奇怪的是,GCC肯定已安装。 退货 但是,当我尝试运行命令“ gcc”时,找不到… 我试图通过yum擦除/安装/重新安装gcc和gcc-c ++,但这似乎无济于事。 有什么建议吗?提前致谢。 问题答案: 您可以通过链接到以下命令来解决此问题: 升级时,您可以保留多
本文向大家介绍C#中尾递归的使用、优化及编译器优化,包括了C#中尾递归的使用、优化及编译器优化的使用技巧和注意事项,需要的朋友参考一下 递归运用 一个函数直接或间接的调用自身,这个函数即可叫做递归函数。 递归主要功能是把问题转换成较小规模的子问题,以子问题的解去逐渐逼近最终结果。 递归最重要的是边界条件,这个边界是整个递归的终止条件。 上面是个经典阶乘函数的实现。这里分2步: 1.转换,把10的阶