short
vsを使用すると、C整数拡張のためにデータ型int
を使用する必要があるという点で、コンパイラーの非効率性が実際に発生することを読みました。int
これは16ビットマイクロプロセッサにも当てはまりますか?
別の質問:1と0の配列がある場合、この16ビットマイクロプロセッサで使用するのが最も効率的ですuint8_t
か?unsigned char
または、intに変換して戻すことにまだ問題があります。
私の心の中でこの泥だらけの問題を解決するのを手伝ってください。ありがとう!
それは本当に問題ですか?私が聞いたほとんどの16ビットシステムではint
、short
同じサイズ(16ビット)になるので、実際には違いはないはずです。
システムに存在する場合uint8_t
、それはと同義になりunsigned char
ます。unsigned char
システムで使用可能な最小の符号なしタイプになります。8ビットを超える場合、はありませんuint8_t
。8ビット未満の場合は、標準に違反しています。一方を他方で定義する必要があるため、効率の違いはありません。
最後に、このような微視的な違いについて本当に心配する必要がありますか?その場合は、アセンブリの出力または(より可能性が高い)プロファイルを確認して、どちらが速いかを確認する必要があります。
16ビット以上のプロセッサでは、ストレージの容量を気にしない場合は、「short」または「signedchar」の代わりに「int」を使用してください。ストレージ要件やラッピング動作を気にしない場合は、「unsignedshort」または「unsignedchar」の代わりに「unsignedint」を使用してください。8ビットプロセッサでは、「char」タイプは「int」よりも高速ですが、16ビット以上のプロセッサでは16ビット演算が32ビット演算よりも高速であるため、「int」は16ビットになる可能性があります。速度のために「short」または「char」を使用する必要はありません。
ところで、一部のプロセッサでは、「unsignedshort」は「unsignedint」よりもはるかに低速です。これは、C標準では符号なし型の操作が「wrap」である必要があるためです。符号なしの短い変数「foo」がレジスタに格納されている場合、「foo +=1;」のコードを生成する一般的なARMコンパイラ。インクリメントを行うための1つの命令と、値を65535に切り捨てるための2つの命令を生成します[BTW、「foo」が65536を超えることはできないことに気付いた最適化コンパイラは、命令を削ることができますが、実際のコンパイラがそうするかどうかはわかりません。 ]。標準では切り捨てが義務付けられていないため、符号付きの「short」は「signedint」よりも遅くする必要はありません。ただし、署名付き型の切り捨てをスキップするコンパイラがあるかどうかはわかりません。
Blackfinでは、16、32、および64ビット命令をサポートし、2つの16ビットMACを備えているため、32ビットタイプと16ビットタイプのどちらが一般的に高いパフォーマンスを生成するかは簡単な答えではありません。操作によって異なりますが、コンパイラオプティマイザがそのような決定を行うことを信頼することをお勧めします。コンパイラオプティマイザは、おそらく気になるよりも、プロセッサの命令のタイミングとスケジューリングについて詳しく知っています。
とはいえ、コンパイラでは、intとshortはどのような場合でも同じサイズである可能性があります。ドキュメントを参照するか、でテストするsizeof
か、ヘッダーを調べてlimits.h
、幅やさまざまなタイプを推測する数値範囲を探してください。
本当にデータ型のサイズを制限したい場合は、stdint.h
などの型を使用してint16_t
ください。
stdint.h
また、などの最速の最小幅整数型を定義しますint_fast16_t
。これにより最小幅が保証されますが、ターゲットでより高速になる場合は、より大きな型が使用されます。これはおそらく問題を解決するための最も移植性の高い方法ですが、使用する適切なタイプについて適切な決定を下したのは実装者に依存しています。ほとんどのアーキテクチャではほとんどまたはまったく違いはありませんが、RISCおよびDSPアーキテクチャではそうではない場合があります。また、特定のサイズがすべての状況で最速であるとは限らない場合もあります。これは、Blackfinの場合に特に当てはまります。
場合によっては(大量のデータが外部メモリから転送される場合)、最速のサイズはデータバスの幅と一致する可能性があります。
バイトサイズに依存するプロジェクトでは、次のようなブロックを使用することにします。
typedef uint8 char
typedef uint16 short
typedef uint32 long
適切なデータ型が何であれ。
変換の問題は、コンパイル時に把握する必要があります。それらはCPUとコンパイラに依存します。
もちろん、16ビットCPUに2つの32ビット数値を追加すると、コンパイラによる調整が必要になります。また、メモリワード幅や任意のアドレスからロードできるかどうか、または特定の境界からバイトをロードする必要があるかどうかによっては、メモリからのロードに没頭するときに面白いことがあります。
、short
YMMVで、プロファイリング後に最適化します。