我的代码中的瓶颈部分存在性能问题。基本上这是一个简单的嵌套循环。
对该问题进行分析表明,该程序花费了大量时间来递增循环计数器 (++) 和测试终止 (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/