C 为什么嵌套for循环比展开同一代码慢得多?

C 为什么嵌套for循环比展开同一代码慢得多?,c,avr,C,Avr,我正在用ATtiny85和128x64px OLED制作一个小玩具控制台。在我的初始构建中,我使用内置的shiftOut()和digitalWrite()函数将显示数据移出屏幕控制器 这让我净赚了5帧,这有点令人失望 我编写了自己的函数,它使用直接端口操作来发送数据,速度大幅提高了~23fps,这还不错。以下是该函数: void shift_out_block(block) { byte b; for (byte i = 0; i < 8; i++) {

我正在用ATtiny85和128x64px OLED制作一个小玩具控制台。在我的初始构建中,我使用内置的
shiftOut()
digitalWrite()
函数将显示数据移出屏幕控制器

这让我净赚了5帧,这有点令人失望

我编写了自己的函数,它使用直接端口操作来发送数据,速度大幅提高了~23fps,这还不错。以下是该函数:

void shift_out_block(block)
{
    byte b;
    for (byte i = 0; i < 8; i++)  
    {
        b = pgm_read_byte(block+i);

        for (byte j=0 ; j < 8 ; j++)
        {
            if ( !!( b & (1 << j)) )
            {
                PORTB |= 1 << SDA;
            }
            else
            {
                PORTB &= ~(1 << SDA);
            }

            PORTB |= 1 << SCL; // HIGH
            PORTB &= ~(1 << SCL); // LOW
        }
    }
}
不费吹灰之力,复制粘贴7次。给了我近75fps的速度-原来的函数执行约42毫秒,新的丑陋的只需约13毫秒

出于兴趣,我将发送位部分分解为一个单独的函数,并调用了8次:

void shift_out_bit(bool bit)
{
    if ( bit )
    {
        PORTB |= 1 << SDA;
    }
    else
    {
        PORTB &= ~(1 << SDA);
    }

    PORTB |= 1 << SCL; // HIGH
    PORTB &= ~(1 << SCL); // LOW
}

void shift_out_block()
{
    byte b;
    for (byte i = 0; i < 8; i++)  
    {
        b = pgm_read_byte(block+i);

        shift_out_bit( !!( b & (1 << 0)) );
        shift_out_bit( !!( b & (1 << 1)) );
        shift_out_bit( !!( b & (1 << 2)) );
        shift_out_bit( !!( b & (1 << 3)) );
        shift_out_bit( !!( b & (1 << 4)) );
        shift_out_bit( !!( b & (1 << 5)) );
        shift_out_bit( !!( b & (1 << 6)) );
        shift_out_bit( !!( b & (1 << 7)) );
    }
}
void shift\u out\u位(bool位)
{
如果(位)
{
PORTB |=1考虑在最内部循环中执行的“有效负载”操作:

  • 检查
    b中的特定位

  • 处理
    PORTB |=1的条件跳转如果您知道这一点,很抱歉,但是,这看起来像是在抨击I2C。ATTiny85有一个硬件I2C。另一个可能没用的评论是,您正在测试if(!!(b&(1@user1228123:这是cargo cult编码(但在这里不应该有害)如果函数采用
    int
    ,而不是
    bool
    void shift\u out\u block(block)
    甚至不是一个有效的函数头。如果你不了解和理解这种语言,你就无法写出好的代码。我有点抨击SPI;)而double-!!是从其他地方复制和粘贴的,我还没有弄清楚它的实际功能,看看我是否可以简化它!这很有意义。我制作了许多“闪烁的灯光”级别的程序,这是我用C尝试过的最复杂的,我不习惯接近金属的特性;)谢谢
    void shift_out_bit(bool bit)
    {
        if ( bit )
        {
            PORTB |= 1 << SDA;
        }
        else
        {
            PORTB &= ~(1 << SDA);
        }
    
        PORTB |= 1 << SCL; // HIGH
        PORTB &= ~(1 << SCL); // LOW
    }
    
    void shift_out_block()
    {
        byte b;
        for (byte i = 0; i < 8; i++)  
        {
            b = pgm_read_byte(block+i);
    
            shift_out_bit( !!( b & (1 << 0)) );
            shift_out_bit( !!( b & (1 << 1)) );
            shift_out_bit( !!( b & (1 << 2)) );
            shift_out_bit( !!( b & (1 << 3)) );
            shift_out_bit( !!( b & (1 << 4)) );
            shift_out_bit( !!( b & (1 << 5)) );
            shift_out_bit( !!( b & (1 << 6)) );
            shift_out_bit( !!( b & (1 << 7)) );
        }
    }