繁体   English   中英

优化级别打破了 C 代码顺序

[英]Optimization level breaks the C code order

我有以下 5 行代码,并希望这行与 O2 或 O3 完全按照此顺序执行:

    PORT->Group[GPIO_PORTB].OUTCLR.reg = (volatile uint32_t) 1 << 9;
    TC3->COUNT16.COUNT.reg =  (volatile uint16_t) 0;
    TC3->COUNT16.CC[0].reg = (volatile uint16_t) vusb_driver->in_data->bitlength;
    SERCOM0->SPI.DATA.reg = (volatile uint32_t) 0x54;
    DMAC->Channel[USB_SEND_SD_DMA_CH].CHCTRLA.reg = (volatile uint8_t) DMAC_CHCTRLA_ENABLE;

如果我使用 O2 或 O3 进行优化,代码会在第 264 行中断,因为该行必须在第 265 行之前执行:

  261:      PORT->Group[GPIO_PORTB].OUTCLR.reg = (volatile uint32_t) 1 << 9;
200001EE   ldr  r1, [pc, #84]        
   263:         TC3->COUNT16.CC[0].reg = (volatile uint16_t) vusb_driver->in_data->bitlength;
200001F0   ldr  r5, [pc, #84]        
   264:         SERCOM0->SPI.DATA.reg = (volatile uint32_t) 0x54;
200001F2   ldr  r4, [pc, #88]        
   265:         DMAC->Channel[USB_SEND_SD_DMA_CH].CHCTRLA.reg = (volatile uint8_t) DMAC_CHCTRLA_ENABLE;
200001F4   ldr  r0, [pc, #88]        
   261:         PORT->Group[GPIO_PORTB].OUTCLR.reg = (volatile uint32_t) 1 << 9;
200001F6   mov.w    r6, #512         
200001FA   str.w    r6, [r1, #148]       
   262:         TC3->COUNT16.COUNT.reg =  (volatile uint16_t) 0;
200001FE   strh r2, [r3, #20]        
   263:         TC3->COUNT16.CC[0].reg = (volatile uint16_t) vusb_driver->in_data->bitlength;
20000200   ldr  r2, [r5]         
20000202   ldr  r2, [r2, #20]        
20000204   ldrh.w   r2, [r2, #72]        
20000208   strh r2, [r3, #28]        
   264:         SERCOM0->SPI.DATA.reg = (volatile uint32_t) 0x54;
2000020A   movs r5, #84      
   265:         DMAC->Channel[USB_SEND_SD_DMA_CH].CHCTRLA.reg = (volatile uint8_t) DMAC_CHCTRLA_ENABLE;
2000020C   movs r2, #2       
   264:         SERCOM0->SPI.DATA.reg = (volatile uint32_t) 0x54;
2000020E   str  r5, [r4, #40]   

 

您对volatile使用是不正确的,您应该将目标对象定义为volatile以确保它们完全按照程序的顺序写入。

如果执行的效果相同(这是“as-if 规则” ),则编译器 - 在常规情况下 - 允许重新排序指令。 因此,您必须执行以下操作之一:

  • 向它表明指令将具有不同的效果(例如,通过使相关的.reg变量可变;或通过指针的别名等)
  • 使用某种特定于编译器的指令来控制其行为。
  • 不编译,即以不同的方式生成您的机器代码。

具体来说,如果您选择第一个选项,您必须向编译器甚至您自己解释,为什么会这样

第 [264] 行必须在第 265 行之前执行

在什么意义上“必须”在 265 之前执行? 谁会注意到? 这个问题的具体答案很可能是您可以用来强制执行所需顺序的东西。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM