6

生産上の問題により、私たちのチームは次の質問に至りました。

  1. GCC 4.4.6 を使用する RHEL6 では、どのようntohsntohl実装されていますか?
  2. 実装は高速または低速であることが知られていますか?
  3. 関数の生成されたアセンブリ コードを実際に確認するにはどうすればよいですか?

質問の背後にある意味がとてつもなくばかげているように思えるかもしれませんが、調査するように依頼されました.

問題のハードウェアは Intel ボックス、リトル エンディアン、64 ビット プロセッサであり、64 ビットでコンパイルされています。

4

4 に答える 4

12

以下をせよ:

test.c

#include <arpa/inet.h>
int main()
{
   volatile uint32_t x = 0x12345678;
   x = ntohl(x);
   return 0;
}

次に、次のようにコンパイルします。

$ gcc -O3 -g -save-temps test.c

結果のファイルを分析するtest.sか、代わりにobjdump -S test.o.

私のマシン(Ubuntu 13.4)では、関連するアセンブラーは次のとおりです。

movl    $305419896, 12(%esp)
movl    12(%esp), %eax
bswap   %eax
movl    %eax, 12(%esp)

ヒント:

  • 305419896 は 10 進数で 0x12345678 です。
  • 12(%esp)volatile 変数のアドレスです。
  • すべてのmovl指示は、のvolatile-ness のためにそこにありxます。本当に興味深い命令は だけですbswap
  • 明らかにntohl、インライン組み込みとしてコンパイルされます。

さらに、(プリコンパイルされた出力) を見ると、が単純に であるtest.iことがわかります。これは、 を呼び出すだけのインライン関数です。ntohl#defined__bswap_32()__builtin_bswap32()

于 2013-07-30T17:25:27.090 に答える
11
  1. /usr/include/bits/byteswap.hこれらは GCC ではなく glibc によって提供され、最適化が有効な場合に使用される__bswap_16および__bswap_32関数を探します(<netinet/in.h>方法の詳細については、を参照してください)。
  2. 使用しているアーキテクチャについては言及していませんが、ビッグ エンディアン システムではノーオペレーションなので、最適な速度で動作します。リトルエンディアンでは、アーキテクチャ固有の手作業で最適化されたアセンブリ コードです。
  3. GCC の-save-tempsオプションを使用して中間.sファイルを保持するか-S、コンパイル後およびコードをアセンブルする前に停止するために使用するか、 http: //gcc.godbolt.org/を使用します。
于 2013-07-30T17:26:20.790 に答える
7

これらは glibc で実装されています。/usr/include/netinet/in.h を見てください。ほとんどの場合、glibc バイトスワップ マクロ (私のマシンでは /usr/include/bits/byteswap.h) に依存します。

これらはヘッダーのアセンブリに実装されているため、かなり高速です。定数の場合、これはコンパイル時に行われます。

于 2013-07-30T17:24:45.073 に答える