3

シフトの動作を確認できるように、実行時にテストを使用してエンディアンを判別することを考えましたが、コンパイラーによるやや独特の最適化に気づきました。それが実行されるマシンのエンディアンは、コンパイル時にわかっていることを示唆します。

これらは私が計時した2つのルーチンです。constを使用するルーチン2は、約33%高速でした。

/* routine 1 */
int big_endian = 1 << 1;
for (register int i = 0; i < 1000000000; ++i) {
  int value = big_endian ? 5 << 2 : 5 >> 2;
  value = ~value;
}
/* routine 2 */
const int big_endian = 1 << 1;
for (register int i = 0; i < 1000000000; ++i) {
  int value = big_endian ? 5 << 2 : 5 >> 2;
  value = ~value;
}

ルーチン2の速度は、コンパイル時に計算可能な定数式を使用する速度と一致します。シフトの動作がプロセッサに依存する場合、これはどのように可能ですか?

また、補足として、最下位桁のビッグエンディアン番号で終わる番号と、上位桁のリトルエンディアン番号で終わる番号を呼び出すのはなぜですか。

編集:

コメントの一部の人々は、ビット単位のシフトはエンディアンとは何の関係もないと主張しています。これが本当の場合、それは3などの数値が常にとして保存され00000011 (big endian)、決して保存されないことを意味します。11000000 (little endian)?これが実際に当てはまる場合、実際には意味があるように見えますが、10000000 00000000 00000000 (128) シフトされているため、リトルエンディアンを使用すると奇妙に動作しません。左に1つは00000000 00000001 00000000 (256)?よろしくお願いします。

4

2 に答える 2

6

コンパイラは、ターゲット プロセッサのエンディアンを想定しています。ほとんどの場合、これは明らかです。たとえば、x86 は常にリトルエンディアンです。どちらかの可能性があるアーキテクチャの場合、デフォルトが機能しない場合、コンパイラの切り替えが頻繁に行われます。たとえば、gcc/arm には-mlittle-endian(デフォルト) と-mbig-endianフラグがあります。

于 2012-08-21T17:47:36.367 に答える