c - 如何优化 C for 循环?

标签 c optimization compiler-construction

我的代码中的瓶颈部分存在性能问题。基本上这是一个简单的嵌套循环。

对该问题进行分析表明,该程序花费了大量时间来递增循环计数器 (++) 和测试终止 (i/j < 8)。

观察汇编输出,我发现两个计数器都没有获取寄存器并且访问它们需要很多周期。使用“register”关键字并不能说服编译器实际将它们放入寄存器中。有什么办法可以优化计数器的访问时间吗?

这是汇编输出。 C 源代码只是一个带有 i/j 计数器的简单嵌套循环。

  2738  0.2479  2459  0.1707   :    1e6c:   jne    1dd1 <process_hooks+0x121>
  1041  0.0942  1120  0.0778   :    1e72:   addl   $0x1,0xffffffd4(%ebp)
  2130  0.1928  2102  0.1459   :    1e76:   cmpl   $0x8,0xffffffd4(%ebp)
  2654  0.2403  2337  0.1622   :    1e7a:   jne    1da0 <process_hooks+0xf0>
  809   0.0732   814  0.0565   :    1e80:   jmp    1ce2 <process_hooks+0x32>

根据要求,这里还有 C 代码。编译器是 gcc 顺便说一句:

for (byte_index=0; byte_index < MASK_SIZE / NBBY; byte_index++)
{
    if (check_byte(mask,byte_index))
    {
        for (bit_index=0; bit_index < NBBY; bit_index++)
        {
            condition_index = byte_index*NBBY + bit_index;
            if (check_bit(condition_mask,condition_index))
            {
                .
                .
                .
            }
        }
    }
}

谢谢

最佳答案

它没有被放入寄存器有两个可能的原因:

变量需要保存在内存中

如果您获取变量的地址或将其声明为易变的,则它不会保存在寄存器中。看起来您没有这样做,但它可能发生在 ... 部分。

gcc 在寄存器分配方面做得不好。

这很有可能。 gcc 似乎有一个糟糕的分配器(基于其开发人员的评论)。此外,寄存器分配变化无常且难以推理。您可能可以使用 register allocator optimizations 对其进行调整以获得一些好处。 .如果您愿意,可以将它们设置为 that function only .

gcc 4.4 有一个新的寄存器分配器,应该会更好,但也允许您选择分配算法。这将提供额外的调整。

您也可以尝试告诉 gcc 更加努力,使用 hot attribute .

最后,您还可以使用 gcc 的 --param 标志进行调整。它们公开了内部编译器设置,因此可能不应轻易着手。

关于c - 如何优化 C for 循环?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1205041/

相关文章:

C - 带循环的多个子叉

c - 如何创建我自己的库以开始使用操作系统?

c - 如何删除 HINSTANCE 到 int 的错误转换?

Oracle:索引中的列顺序重要吗?

c - 如何编译C程序?

c - 如何在一个数组中存储3种不同类型的数据

r - 为什么 mean() 这么慢?

c - C 中的结构填充

recursion - 在函数式语言中,编译器如何将非尾递归转换为循环以避免堆栈溢出(如果有的话)?

c - 预处理器是否在编译器开始运行之前准备了一个唯一常量字符串列表?