gpt4 book ai didi

c++ - 编译器优化如何加快简单操作之间的时间?

转载 作者:行者123 更新时间:2023-11-28 00:24:03 25 4
gpt4 key购买 nike

我有一个使用 SPI 的嵌入式 C++ 项目。当我在没有优化 (-O0) 的情况下编译和运行我的程序时,外围设备(LCD 面板)工作正常。当我使用 优化(-O1) 编译它时,外围设备无法正常工作。

我用逻辑分析仪检查了这两种情况,唯一的区别是优化后的代码写入字节之间的时间要短得多(时钟速率、写入的字节数等相同)。编译器优化如何影响后续操作之间的时间,这些操作只是一个接一个地写入硬件寄存器?如果我在 SPI 类中的每个写入命令之后添加一个延迟,它会在优化的情况下工作。

与下面的示例不同,在原始代码中,对WriteCommand()WriteData() 的调用是通过一个指针。

代码片段,通过 SPI 连续写入外设:

{
SPI m_spiPort();
m_spiPort.Init();

m_spiPort.WriteCommand(SLEEPOUT);

// Color Interface Pixel Format (command 0x3A)
m_spiPort.WriteCommand(COLMOD);
m_spiPort.WriteData(0x03); // 0x03 = 12 bits-per-pixel

// Memory access controller (command 0x36)
m_spiPort.WriteCommand(MADCTL);
m_spiPort.WriteData(0x00);

// Write contrast (command 0x25)
m_spiPort.WriteCommand(SETCON);
m_spiPort.WriteData(0x39); // contrast 0x30

// Display On (command 0x29)
m_spiPort.WriteCommand(DISPON);

}

SPI 类:

class SPI {
public:
void Init();
void WriteCommand(unsigned int command);
void WriteData(unsigned int data);
private:
void Write(unsigned int value);
};

这个类的实现是:

void SPI::WriteCommand(unsigned int command)
{
command &= ~0x100; //clear bit 8
Write(command);
}

void SPI::WriteData(unsigned int data)
{
data |= 0x100; //set bit 8
Write(data);
}

void SPI::Write(unsigned int value)
{
LPC_SSP->DR = value;
}
void SPI::Init( void )
{
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<11); //Enables clock for SPI
LPC_SYSCON->SSPCLKDIV = 0x01;

LPC_IOCON->PIO0_14 &= ~(0x7); // SCK
LPC_IOCON->PIO0_14 |= 0x2;

LPC_IOCON->PIO0_17 &= ~(0x7); // MOSI
LPC_IOCON->PIO0_17 |= 0x2;

/* SSP SSEL is a GPIO pin */
LPC_IOCON->PIO0_27 = 0x0; // configure as GPIO pin
LPC_GPIO0->MASK = (1<<27);
LPC_GPIO0->DIR |= (1<<27); // set in output mode */
LPC_GPIO0->CLR = 1 << 27;

/* Set DSS data to 9-bit, Frame format SPI, CPOL = 0, CPHA = 0, and SCR is 0 */
LPC_SSP->CR0 = 0x0008;

/* SSPCPSR clock prescale register, master mode, minimum divisor is 0x02 */
LPC_SSP->CPSR = 0x4; // SPI clock will run at 6 MHz

/* set Master mode and enable the SPI */
LPC_SSP->CR1 = 0x2;
}

编辑 - 从 SPI::Write() 中删除了 DelayInCycles()。没有它,差异仍然很明显,我并不是要将它包括在这篇文章中。

最佳答案

对于每个命令和数据字节,您的代码调用两个函数,并且两个函数都没有局部变量或许多临时变量。

当忠实地实现时,这些函数中的每一个都将创建一个堆栈帧(需要一些指令来设置和拆除)来存储不能保存在寄存器中的任何局部变量和临时变量。这可能是在 -O0 编译模式下发生的情况。

影响此类代码执行时间的两个重要优化是:

  • 堆栈帧遗漏:编译器注意到Write(可能还有WriteCommandWriteData)的堆栈帧未被使用,因此决定消除设置(和拆除)堆栈框架的说明。
  • 函数内联:由于WriteWriteCommandWriteData都是非常简单的函数,编译器可以决定去掉该函数完全调用并生成代码,就像您编写的一样(忽略任何可访问性问题):

    {
    SPI m_spiPort();
    m_spiPort.Init();

    m_spiPort.LPC_SSP->DR = (SLEEPOUT & ~0x100);

    // Color Interface Pixel Format (command 0x3A)
    m_spiPort.LPC_SSP->DR = (COLMOD & ~0x100);
    m_spiPort.LPC_SSP->DR = (0x03 & 0x100);

    // Memory access controller (command 0x36)
    m_spiPort.LPC_SSP->DR = (MADCTL & ~0x100);
    m_spiPort.LPC_SSP->DR = (0x00 & 0x100);

    // Write contrast (command 0x25)
    m_spiPort.LPC_SSP->DR = (SETCON & ~0x100);
    m_spiPort.LPC_SSP->DR = (0x39 & 0x100);

    // Display On (command 0x29)
    m_spiPort.LPC_SSP->DR = (DISPON & ~0x100);
    }

这两种优化都消除了实际写入寄存器之间的许多(簿记)指令,从而使写入速度更快。

关于c++ - 编译器优化如何加快简单操作之间的时间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25975249/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com