2

私は、gcc/x86 でこの小さな関数を使用して、int16_t の高速なバイト交換を行っています。

static inline int16_t MySwapInt16t(int16_t val)
{
   __asm__ ("xchgb %b0, %h0" : "=Q" (val) : "0" (val));
   return val;
}

...今日、他の誰かのコードをオンラインで閲覧しているときに、彼が次のような同様の関数を持っているのを見ました:

static inline int16_t HisSwapInt16t(int16_t val)
{
   __asm__ ("xchgb %h0, %b0" : "+Q" (val));
   return val;
}

私の機能と彼の機能(AFAICT)の違いは次のとおりです。

  1. 彼は「=Q」の代わりに「+Q」を指定します
  2. %h0 と %b0 の位置が入れ替わっています
  3. 関数の最後に : "0" (val) 句がありません

私が知る限り、両方の実装は正しく機能しているように見えますが、インライン アセンブリは私にとっては少し難しいので、知識のある人が説明してくれます:

  1. 上記の 3 つの違いの意味は何ですか?
  2. 2 つの実装のうちの 1 つは、他の実装よりも優れているか、または高速ですか? それとも、両方とも同等に機能しますか?
4

1 に答える 1

0

彼は「=Q」の代わりに「+Q」を指定します

関数の最後に : "0" (val) 句がありません

修飾子は入力オペランドと出力オペランドの+両方を表すため、入力リストを追加する必要はありません。それについてはCGG のマニュアルを確認してください。

%h0 と %b0 の位置が入れ替わっています

xchg命令は 2 つのオペランド間でコンテンツ交換を行うため、問題ではないと思います。

2 つの実装のうちの 1 つは、他の実装よりも優れているか、または高速ですか? それとも、両方とも同等に機能しますか?

最適な実装を見つけるには、両方をコンパイルしobjdump、コンパイラがこれらの関数をどのようにラップしたかを確認します。これは、コア関数が同じ単一の命令になるためです。

この助けを願っています!

于 2012-06-12T21:17:59.700 に答える