単語を 2 バイトに分割する最速の方法は何ですか?
short s = 0x3210;
char c1 = s >> 8;
char c2 = s & 0x00ff;
対
short s = 0x3210;
char c1 = s >> 8;
char c2 = (s << 8) >> 8;
編集
どうですか
short s = 0x3210;
char* c = (char*)&s; // where c1 = c[0] and c2 = c[1]
単語を 2 バイトに分割する最速の方法は何ですか?
short s = 0x3210;
char c1 = s >> 8;
char c2 = s & 0x00ff;
対
short s = 0x3210;
char c1 = s >> 8;
char c2 = (s << 8) >> 8;
どうですか
short s = 0x3210;
char* c = (char*)&s; // where c1 = c[0] and c2 = c[1]
この作業はコンパイラーに任せてください。union
手動でビットシフトを行わずにバイトを分割する場合は、を使用します。擬似コードを見てください:
union U {
short s; // or use int16_t to be more specific
// vs.
struct Byte {
char c1, c2; // or use int8_t to be more specific
}
byte;
};
使い方は簡単です:
U u;
u.s = 0x3210;
std::cout << u.byte.c1 << " and " << u.byte.c2;
概念は単純です。その後、必要に応じて演算子をオーバーロードして、より洗練されたものにすることができます。
コンパイラによって と の順序c1
がc2
異なる場合がありますが、それはコンパイル前にわかることに注意してください。いくつかの条件付きマクロを設定して、任意のコンパイラで必要に応じて順序を設定できます。
ほぼすべてのアーキテクチャで、最初のものは少なくとも 2 番目のものと同じくらい高速であると 99.9% 確信しています。違いがない (等しい) アーキテクチャがいくつかあるかもしれません。また、いくつかのアーキテクチャでは、後者の方が遅くなります。
2番目の方が遅い主な理由は、c2
数字を出すために2つのシフトがあるためです. プロセッサは、最初のシフトが完了するまで、2 番目のシフトの処理を開始できません。
また、コンパイラは最初のもので他の巧妙なことを行うことができるかもしれません (それを行う命令がある場合 - たとえば、x86 プロセッサがs
AX にロードし、AL を格納しc1
、AH を格納することができますc2
- ストアを超えた余分な命令はありません)操作)、2番目のものは「既知の一般的なパターン」である可能性がはるかに低いです(shift/and
メソッドが非常に一般的に使用されているコードでそのバリアントが使用されているのを見たことはありません-多くの場合、「ピクセルループ」で、重要であることを意味します)適切な最適化を実装するため)。
いつものように、測って測ってまた測る。また、特定のマシンのパフォーマンスのみに関心がある場合を除き、異なるモデル/プロセッサの製造元で試してみてください。そうすれば、マシンのモデルで 5% 速くなるものを作成することはできませんが、別のモデルでは 20% 遅くなります。
でそれぞれの時間を測定する必要がありますfor (long i = 0; i < 100000000; i++)
。私はそうしました、そしてより速いのは最初のものでした(0.82秒対0.84秒)。MVS でこれを行う簡単な方法は、監視を設定すること@clk
です。
下位バイトを抽出するには、マスクや 2 つのシフトではなく、必ずキャストを使用する必要があります。コンパイラは、すでに最速であるとわかっていることを実行します。これにより、選択肢が 1 つしかない上位ビットが残ります。