高速整数型が他の整数型よりも速いのはなぜですか?


107

ISO / IEC 9899:2018(C18)では、7.20.1.3に規定されています。

7.20.1.3最短の最小幅整数型

1次の各タイプは、少なくとも指定された幅を持つすべての整数型の中で動作するのに通常最も高速な整数型を指定しています268)

2 typedef名int_fastN_tは、幅がN以上uint_fastN_tの最速の符号付き整数型を示します。typedef名は、幅がN以上の最速の符号なし整数型を示します。

3次のタイプが必要です。

int_fast8_tint_fast16_tint_fast32_tint_fast64_tuint_fast8_tuint_fast16_tuint_fast32_tuint_fast64_t

このフォームの他のすべてのタイプはオプションです。


268)指定されたタイプがすべての目的で最速であるとは限りません。実装が1つの型を選択する明確な根拠がない場合、符号型と幅の要件を満たす整数型を選択するだけです。


しかし、これらの「高速」整数型がより高速である理由は明記されていません。

  • これらの高速整数型が他の整数型よりも速いのはなぜですか?

高速整数型はC ++ 17のヘッダーファイルでも利用できるため、C ++で質問にタグを付けましたcstdint。残念ながら、ISO / IEC 14882:2017(C ++ 17)では、その説明についてそのようなセクションはありません。それ以外の場合は質問の本文にそのセクションを実装しました。


情報:Cでは、のヘッダーファイルで宣言されていますstdint.h


24
ここで重要なのは、これらの整数型は分離されておらず、魔法のように高速な型であることです。それらは、通常の既存の型のエイリアスであり、その操作でそのマシン上で最も高速です。
mtraceur

3
コンパイラーは、特定のサイズのメモリー位置とレジスターをロード、保管、マスク、および変更するためのCPU操作オペコードを発行します。それはCPUが見るすべてです。オペレーティングシステムは、それとはまったく関係ありません。指定したtypedefを自分で指定した場合とまったく同じように、コンパイラーがすべてを行います。(コンパイラーは、動作に目に見える違いがない限り、ユーザーのtypedefよりも、おそらく可能であれば、より効率的に)コンパイラーが内部的に異なる方法で処理することを許可されていると思います。)
Peter-Monica

1
@ RobertS-ReinstateMonica正確には、これらの「エイリアス」は単なるtypedefステートメントです。したがって、通常は標準ライブラリレベルで行われます。どのような彼らの当然のことながら、C標準プット本当制限しないtypedefので、例えば典型的な実装を作ることです-への32ビットシステムではなく、架空のコンパイラができ、たとえば実装するいくつかの空想を行うには組み込み型との約束をそのタイプの変数に対してケースバイケースで最速のマシンタイプを選択するための最適化、そしてライブラリはそれを可能にします。int_fast32_ttypedefint__int_fasttypedef
mtraceur

1
@ RobertS-ReinstateMonicaはい、そうです。アーキテクチャ固有のコンパイルフラグを使用して最大のパフォーマンスプログラムを取得すると、バイナリの移植性が低下します。
ピーター-

1
ロバーツ-ReinstateMonica @それは、それがコンパイルされたプラットフォーム上で最も効率的になるために必須ではないが、
HABO

回答:


152

64ビット算術演算のみを実行するCPUを想像してみてください。次に、このようなCPUに符号なし8ビット加算を実装する方法を想像してください。正しい結果を得るには、必ず複数の操作が必要になります。このようなCPUでは、64ビット操作は他の整数幅の操作よりも高速です。この状況では、すべてXint_fastY_tがおそらく64ビットタイプのエイリアスである可能性があります。

CPUが狭い整数型の高速演算をサポートしているため、幅の広い型の方が幅の狭い型よりも速くXint_fastY_tない場合、すべてのYビットを表すのに必要なよりも広い型のエイリアスにはなりません。

好奇心から、いくつかのアーキテクチャの特定の実装(GNU、Linux)でサイズを確認しました。これらは、同じアーキテクチャのすべての実装で同じではありません。

┌────╥───────────────────────────────────────────────────────────┐
 Y     sizeof(Xint_fastY_t) * CHAR_BIT                         
    ╟────────┬─────┬───────┬─────┬────────┬──────┬────────┬─────┤
     x86-64  x86  ARM64  ARM  MIPS64  MIPS  MSP430  AVR 
╞════╬════════╪═════╪═══════╪═════╪════════╪══════╪════════╪═════╡
 8   8       8    8      32   8       8     16      8   
 16  64      32   64     32   64      32    16      16  
 32  64      32   64     32   64      32    32      32  
 64  64      64   64     64   64      64    64      64  
└────╨────────┴─────┴───────┴─────┴────────┴──────┴────────┴─────┘

より大きな型での操作はより高速になる可能性がありますが、そのような型はキャッシュ内でより多くのスペースを必要とするため、それらを使用してもパフォーマンスが向上するとは限りません。さらに、そもそも実装が正しい選択をしたと常に信頼できるわけではありません。いつものように、最適な結果を得るためには測定が必要です。


Androidユーザー向けの表のスクリーンショット:

上記の表のスクリーンショット

(Androidのモノフォントにはボックス描画文字がありません-ref


コメントは詳細な議論のためのものではありません。この会話はチャットに移動さました
Samuel Liew

@RobertSsupportsMonicaCellioいいえ。「すべてのアーキテクチャで同じではない」も当てはまりますが、表示されたデータからすぐにわかるため、明白なことを述べる必要はないと考えます。私は1つの実装からの値のみを示しましたが、実際には他の実装には異なる選択肢があります。たとえば、Windowsのx86-64を確認します。ここに示されているものとは異なるサイズが表示されます。
eerorika

@RobertSsupportsMonicaCellio私の意見では、これらのコメントは回答に関連しており、ここで適切です。必要に応じて、モデレーターに移動を依頼します。
eerorika

11

それらは、少なくとも確実ではありません。

高速型は通常の型の単純なtypedefですが、それらを定義する方法は実装次第です。それらは少なくとも要求されたサイズでなければなりませんが、もっと大きくすることもできます。

一部のアーキテクチャでは、一部の整数型のパフォーマンスが他の型よりも優れていることは事実です。たとえば、初期のARM実装には、32ビットワードと符号なしバイトに対するメモリアクセス命令がありましたが、ハーフワードまたは符号付きバイトに対する命令はありませんでした。ハーフワードと符号付きバイトの命令は後で追加されましたが、予備のエンコーディングスペースに詰め込む必要があったため、アドレス指定オプションの柔軟性は低くなっています。さらに、ARMの実際のデータ処理命令はすべてワードで機能するため、正しい結果を得るには、計算後に小さい値をマスクする必要がある場合があります。

ただし、より小さな値をロード/保存/処理するためにより多くの命令を必要とする場合でも、キャッシュ圧力の競合する懸念もあります。キャッシュミスの数を減らすと、小さい値でもパフォーマンスが向上する可能性があります。

多くの一般的なプラットフォームでの型の定義は十分に検討されていないようです。特に、最新の64ビットプラットフォームは32ビット整数を適切にサポートする傾向がありますが、これらのプラットフォームでは「高速」型が不必要に64ビットであることがよくあります。

さらに、Cの型はプラットフォームのABIの一部になります。そのため、プラットフォームベンダーが馬鹿な選択をしたことに気付いたとしても、後でそれらの馬鹿な選択を変更することは困難です。

「高速」タイプは無視してください。整数のパフォーマンスが本当に心配な場合は、使用可能なすべてのサイズでコードをベンチマークしてください。


7

高速型は他のすべての整数型よりも高速ではありません-実際には、いくつかの「通常の」整数型と同じです(それらはその型の単なるエイリアスです)。少なくともそのビット数。

それは、プラットフォームに依存し、各高速タイプがエイリアスである整数タイプです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.