C 为什么编译器不优化中断代码?

C 为什么编译器不优化中断代码?,c,optimization,interrupt-handling,cortex-m3,C,Optimization,Interrupt Handling,Cortex M3,我最近遇到了一个问题,一个变量只在中断处理程序中被修改。变量本身没有声明为volatile,因此在更高级别的优化中,编译器会破坏代码。但是,编译器足够聪明,可以编译中断代码,因为中断仍然会触发 下面是我的问题: 如果编译器足够聪明,可以编译中断代码,为什么它不够聪明,不能意识到变量在中断内部发生了变化 在更高级别的优化中,未调用的函数将得到优化。由于没有代码调用中断处理程序,因此应该对其进行优化。究竟是什么导致编译器编译中断代码 语言执行模型说,普通的非易失性变量不能被外力改变。也就是说,如果您

我最近遇到了一个问题,一个变量只在中断处理程序中被修改。变量本身没有声明为volatile,因此在更高级别的优化中,编译器会破坏代码。但是,编译器足够聪明,可以编译中断代码,因为中断仍然会触发

下面是我的问题:

如果编译器足够聪明,可以编译中断代码,为什么它不够聪明,不能意识到变量在中断内部发生了变化

在更高级别的优化中,未调用的函数将得到优化。由于没有代码调用中断处理程序,因此应该对其进行优化。究竟是什么导致编译器编译中断代码

语言执行模型说,普通的非易失性变量不能被外力改变。也就是说,如果您的代码流没有显式地更改变量,那么从该代码流的角度来看,该变量不可能更改。除了C11定义的多线程执行之外。您必须手动指定可由中断处理程序更改的变量

这是实现C代码高效优化的主要因素之一。如果不对C程序的性能产生重大的负面影响,它是无法消除的

首先,编译器通常不会使用外部链接优化掉函数。中断处理程序是否用外部链接声明

第二,优化或保留函数的决定实际上并不取决于函数是否被调用。它基于程序中是否以任何方式引用了相应的符号。将删除未引用的符号,而保留引用的符号。除了调用函数符号外,还有其他方法引用函数符号。例如,取函数的地址也算作对函数符号的引用。地址在程序中任意位置的函数永远不会被优化掉

中断向量项在程序启动时以某种方式初始化,这通常涉及获取处理程序函数的地址。这已经足以保护此功能不被优化

语言执行模型说,普通的非易失性变量不能被外力改变。也就是说,如果您的代码流没有显式地更改变量,那么从该代码流的角度来看,该变量不可能更改。除了C11定义的多线程执行之外。您必须手动指定可由中断处理程序更改的变量

这是实现C代码高效优化的主要因素之一。如果不对C程序的性能产生重大的负面影响,它是无法消除的

首先,编译器通常不会使用外部链接优化掉函数。中断处理程序是否用外部链接声明

第二,优化或保留函数的决定实际上并不取决于函数是否被调用。它基于程序中是否以任何方式引用了相应的符号。将删除未引用的符号,而保留引用的符号。除了调用函数符号外,还有其他方法引用函数符号。例如,取函数的地址也算作对函数符号的引用。地址在程序中任意位置的函数永远不会被优化掉

中断向量项在程序启动时以某种方式初始化,这通常涉及获取处理程序函数的地址。这已经足以保护此功能不被优化


发布您的代码,可能还有相关的解构。您使用的编译器是什么?它是的最新版本吗?优化标志是什么?目标平台和处理器是什么?为什么不在你的例子中使用volatile呢?可能是因为当你加载带有地址的向量中断控制器时,它被引用了?如果引用了处理程序的地址,那么编译器将假定它可能被调用。发布您的代码,可能还有相关的反汇编。您使用的编译器是最新版本的吗?优化标志是什么?目标平台和处理器是什么?为什么不在你的例子中使用volatile呢?可能是因为当你加载带有地址的向量中断控制器时,它被引用了?如果引用了处理程序的地址,那么编译器将假定它可能被调用。我使用的是stm32处理器,制造商的支持库已经掩盖了许多中断链接细节。我知道我需要在代码中的某个地方编写TIM4_IRQHandler,链接器将该处理程序放置在向量部分的正确位置。编译器保留该函数,因为链接器
将TIM4_IRQHandler的地址放在向量部分。这就是我所假设的情况。@thndrwrks:如果您的实现提供了一些隐式的引擎盖下功能,确保您的TIM4_IRQHandler被放置在中断向量中的正确位置,那么,很可能同样的功能也会采取所有必要的步骤来防止TIM4_IRQHandler被优化掉。这确实是正在发生的事情。获取VIC处理程序的地址意味着编译器假定可以调用它。我使用的是stm32处理器,制造商的支持库已经掩盖了许多中断链接细节。我知道我需要在代码中的某个地方编写TIM4_IRQHandler,链接器将该处理程序放置在向量部分的正确位置。编译器保留该函数,因为链接器将TIM4_IRQHandler的地址放在vector部分。这就是我所假设的情况。@thndrwrks:如果您的实现提供了一些隐式的引擎盖下功能,确保您的TIM4_IRQHandler被放置在中断向量中的正确位置,那么,很可能同样的功能也会采取所有必要的步骤来防止TIM4_IRQHandler被优化掉。这确实是正在发生的事情。获取VIC处理程序的地址意味着编译器假定可以调用它。