如何告诉GCC/Clang优化器生成特定的操作序列

问题描述 投票:0回答:1

我有一个循环需要按特定顺序执行操作序列。我在这里所做的是多次手动展开循环:

loop
{
    delta = get_delta();
    sum1 += delta;
    sum2 += delta;
    sum3 += delta;

    delta = get_delta();
    sum1 += delta;
    sum2 += delta;
    sum3 += delta;
}

查看生成的汇编代码,有时编译器会将此循环优化为如下所示:

loop
{
    delta1 = get_delta();
    delta2 = get_delta();
    delta_sum = delta1 + delta2;

    sum1 += delta_sum;
    sum2 += delta_sum;
    sum3 += delta_sum;
}

我不希望这种情况发生,因为该行为并不完全复制循环展开。我一直在通过

__asm__
关键字研究内联汇编提示,但无法完全使其可靠地工作。我也不想使用
volatile
变量,因为这会导致从内存加载,而不是使用寄存器。在构建时将优化标志更改为
-O0
-O1
并不理想,因为这不能保证始终在不同的编译器版本等下产生一致的结果。

有谁知道我可以使用

__asm__
或类似的技巧,以便我可以完全按照源代码中编写的顺序展开循环,而不必编写汇编代码?

c gcc clang compiler-optimization loop-unrolling
1个回答
0
投票

在尝试了各种

__asm__ volatile ()
语句和不同的编译器优化选项之后,很明显循环展开(无论是自动还是手动)都会产生太多副作用。编译器执行各种代码优化和消除,从而产生非常不同的代码结构。

为了通过定时循环获得一致的结果,应执行以下操作:

  1. 使用

    _Pragma ("GCC unroll 1")
    -fno-unroll-loops
    完全禁用特定翻译单元的循环展开。

  2. 增加循环内的指令数量,以减少循环开销,从而使大量循环迭代的测量结果出现偏差。

  3. 不要使用

    -O0
    或类似的,这太粗糙了并且会禁用许多其他有用的优化。

© www.soinside.com 2019 - 2024. All rights reserved.