2

以下を考えると:

#include <stdint.h>
#include <stdio.h>

uint16_t foo(uint8_t* x)
{
  uint16_t r = (x[1] << 8) | x[0];
  return r;
}

uint16_t bar(uint8_t* x)
{
  uint16_t r = ((uint16_t*) x)[0];
  return r;
}

x86_64 では、GCC と Clang の両方で次のようなコードが生成されます。

foo:                                    # @foo
        .cfi_startproc
# BB#0:                                 # %entry
        movzbl  (%rdi), %ecx
        movzbl  1(%rdi), %eax
        shll    $8, %eax
        orl     %ecx, %eax
        movzwl  %ax, %eax
        ret

bar:                                    # @bar
        .cfi_startproc
# BB#0:                                 # %entry
        movzwl  (%rdi), %eax
        ret

foo が bar と同等になるように最適化されていない (つまり、単一の 16 ビット ロードを実行している) 理由はありますか? 負荷の調整?

4

1 に答える 1

2

私はコンパイラを書いていませんが、推測はできます:

コンパイラが使用する標準の最適化手法はどれも、.xml のコードには影響しませんfoo。同等であることを検出するにbarは、この特定のパターンを見つけるように設計された特定の最適化が必要であり、代わりに「改善された」コードを出力します。

では、なぜこれに対する特定の最適化がないのでしょうか? おそらく通常の理由:

「投資対効果が不十分」

言い換えれば、コーディング、デバッグ、最適化の維持に費やされる時間、およびこのパターンのソースのすべての行をチェックするために費やされる余分なコンパイル時間は、そこから得られる利益を台無しにしてしまいます。

そしてもちろん、あなたはhtons/ntohsすでに持っています。私はそれらを使用します。

負荷の調整?

それは興味深いものであり、私はそれを調べなければなりませんでした。着信ポインター 'x' がワード アライメントされていない場合、bar多くのアーキテクチャでクラッシュしますが、foo動作するはずです。

ただし、x86 アーキテクチャでは、位置合わせされていないロードが許可されるため、両方の関数は、位置合わせされていない x の値に対しても機能するはずです。

于 2012-05-31T19:22:29.300 に答える