現在、32ビットMIPSプラットフォーム向けのコードベース(C、C++混合)を使用しています。プロセッサはかなり現代的なものです(処理能力とメモリが十分にあることは言うまでもありません)。
コードベースは、uint8 [1バイト幅の符号なし整数]、uint16 [2バイト幅の符号なし整数]、uint32 [4バイト幅の符号なし整数]などのデータ型を使用します。
コードを異なるプラットフォームに移植する際に、これらの構造の使用がどのように役立つかを知っています。
私の質問は:
Uint32でも十分である(もしあれば)uint16を使用する際の使用/利点は何ですか?
短いデータ型を使用すると、メモリ使用量が節約されますか(データのアライメントを考慮)。
数バイトのメモリを節約する場合、最新のハードウェアで行うのは賢明なことですか?
Uint32でも十分である(もしあれば)uint16を使用する際の使用/利点は何ですか?
それらのuint16s
が配列または構造の一部である場合、メモリを節約でき、おそらく同じ配列または構造でuint32s
を使用するよりも大きなデータセットを処理できます。本当にあなたのコードに依存します。
データプロトコルとファイル形式はuint16s
を使用する場合があり、代わりにuint32s
を使用するのは正しくない場合があります。これは、形式とセマンティクスに依存します(たとえば、65535から0にラップする値が必要な場合、uint16
は自動的に処理しますが、uint32
は処理しません)。
OTOH、それらのuint16s
が単一のローカル変数またはグローバル変数である場合、32ビット変数で置き換えても、アライメントのために同じスペースを占有する可能性があり、32ビットパラメーターとして渡されるため、大きな違いはありませんとにかくMIPSで(スタックまたはレジスターで)。
短いデータ型を使用すると、メモリ使用量が節約されますか(データのアライメントを考慮)。
特にuint16s
が多くの構造の一部または大きな配列の要素である場合、節約があります。
数バイトのメモリを節約する場合、最新のハードウェアで行うのは賢明なことですか?
はい、メモリ帯域幅を下げます(これは常に良いことです)。また、少ないデータで操作する場合、さまざまなキャッシュミス(データキャッシュとTLB)を下げることがよくあります。
まず、uint16などのタイプが定義されている場合、どこで定義されていますか?これらは標準タイプではないため、独自のヘッダーで定義されます-おそらく自分のものであるか、サードパーティライブラリによって提供される可能性があります。その場合、そのコードの移植性と、他のアプリケーションでは意味をなさない依存関係を作成しているかどうかを自問する必要があります。
別の問題は、多くのライブラリ(不適切なIMO)がUINT16、uint16、U16 UI16などのさまざまな名前でそのような型を定義することで、型の一致を保証し、名前の衝突を回避するのはやや悪夢になります。このような名前areが定義されている場合、理想的には名前空間に配置するか、使用するために定義されたライブラリを示すライブラリ固有のプレフィックスを指定する必要があります(例:_rtos::uint16
_ to _rtos_uint16
_。
ISO C99標準ライブラリはstdint.hで標準のビット長固有の型を提供するため、独自のヘッダーまたはサードパーティのヘッダーで定義されているものよりも、その使用を優先する必要があります。これらのタイプには__t
_サフィックスがあります。 _uint16_t
_。 C++では、_std::
_名前空間に配置できます(ただし、ヘッダーはC99で導入されたため、これは指定されていません)。
1] uint32でも十分な場合にuint16を使用する場合の使用/利点は何ですか(ある場合)。
_stdint.h
_の_uint16_t
_を優先するという以前のアドバイスとは別に、長さ固有の型を使用する正当な理由が少なくとも2つあります。
2]短いデータ型を使用すると、メモリ使用量が節約されますか(データのアライメントを考慮)。
おそらく、しかし、メモリがあなたの問題でないならば、それはそれらを使用する正当な理由ではありません。おそらく大きなデータオブジェクトまたは配列を検討する価値はありますが、グローバルに適用することは努力する価値はほとんどありません。
3]数バイトのメモリを節約する場合、最新のハードウェアで行うのは賢明なことですか?
[2]を参照してください。 "現代のハードウェア"は、必ずしも大きなリソースを意味するわけではありません。多くの32ビットARM少数のCortex-MデバイスKb of RAM。たとえば、設計やアーキテクチャの時代よりも、ダイのスペース、コスト、消費電力の方が重要です。
cstdint
には、さまざまな目的でtypedef
sの負荷があります。
intN_t
特定の幅int_fastN_t
少なくともNビットの最速の整数int_leastN_t
少なくともNビットの最小整数unsigned
に相当するもの状況に応じて選択する必要があります。 std::vector
と計算の負荷をしていない? intN_t
はおそらくあなたの男です。少数の整数で高速計算が必要ですか? int_fastN_t
はおそらくあなたの男です。
生成されたマシンコード/アセンブラをチェックして、コードが保存されていることを確認する必要があります。 RISCタイプのアーキテクチャでは、一般的なイミディエートは16ビットですが、uint16_tを使用すると、とにかく完全な32ビットレジスタが消費されます。したがって、int型を使用する場合、ゼロに近い値を使用すると、同じ結果が得られ、移植性が向上します。
メモリを節約するIMOは、最新のプラットフォームでも価値があります。より厳しいコードは、例えばより良いバッテリー寿命とより流なUX。ただし、(大)配列を操作する場合、または変数が実際のHWリソースにマップされる場合にのみ、サイズをマイクロ管理することをお勧めします。
追伸コンパイラーは賢いですが、それらを書いている人々は、現時点ではそれらをさらに良くします。
回答1.ソフトウェアには、エンコード/デコードまたはその他の特定の用途で8/16ビットのパラメーターのみを使用するよう厳密に指示する特定の要件と仕様があります。したがって、u8 sayに127より大きい値を割り当てても、データは自動的にトリムされます。
回答2.コンパイラーは、メモリーであろうと複雑であろうと、最適化を行うにはインテリジェントをはるかに超えていることを忘れてはなりません。そのため、可能な限り小さいメモリを使用することを常にお勧めします。
回答3.もちろん、メモリの節約は現代のハードウェアでは理にかなっています。
int32_t
などの正確な幅の整数型とその友人を使用すると、int
とlong
のサイズが異なるプラットフォーム間の符号拡張バグを回避するのに役立ちます。これらは、ビットマスクの適用時やビットシフト時などに発生する可能性があります。たとえばlong
でこれらの操作を行い、コードが32ビットlong
で機能する場合、64ビットlong
で機能しなくなる可能性があります。一方、uint32_t
を使用すると、プラットフォームに関係なくどのような結果が得られるかを正確に把握できます。
また、プラットフォーム間でバイナリデータを交換する場合にも役立ちます。この場合、ビット幅ではなく、保存されたデータのエンディアン性のみを考慮する必要があります。 int64_t
をファイルに書き込むと、別のプラットフォームでそれを読み取ってint64_t
に保存できることがわかります。あるプラットフォームで64ビットの代わりにlong
を書き込む場合、long
は32ビットしかないため、別のプラットフォームでlong long
が必要になる可能性があります。
非常に限られた環境(組み込みのもの)や大きなデータセット(5000万個の要素を含む配列など)について話していない限り、通常、メモリを節約することは理由ではありません。
uint16_t
の代わりにuint32_t
を使用すると、メモリが節約されます。また、ハードウェアの制約かもしれません(たとえば、一部の周辺コントローラーは実際に16ビットを送信しています!)。ただし、キャッシュとアライメントの考慮事項のため、使用する価値がない場合があります(ベンチマークが必要です)。
Uint32でも十分である(もしあれば)uint16を使用する際の使用/利点は何ですか?
unsigned char
が16ビット値であるCPUがあります。このようなコードのユニットテストは、typedefを使用しないと困難になります(uint16は、適切なタイプの単なるtypedefです)。
また、これらのtypedefを使用すると、さまざまなプラットフォームで多くの問題なく簡単にビルドできます。
短いデータ型を使用すると、メモリ使用量が節約されますか(データのアライメントを考慮)。
いいえ、それはポイントではありません。 uint16
がunsigned short
のtypedefである場合、どこでもunsigned short
を使用できますが、プラットフォームごとに異なる型を取得できます。
もちろん、より小さな型を使用すると、メモリ消費が削減されます。たとえば、配列を使用する場合にのみ、uint32の代わりにuint16を使用します。
数バイトのメモリを節約する場合、最新のハードウェアで行うのは賢明なことですか?
それはプラットフォームに依存します:
質問に対する答えは、1つの重要な概念に要約されます。データはどれくらいの大きさですか?大量に処理している場合は、より小さなデータ型を使用することの利点は明らかです。このように考えてください。新しく発見された最大の既知の素数を計算するだけで、一般的なワークステーションのメモリが不足する可能性があります。数値自体は、保存するだけで1ギガバイト以上かかります。実際の数を計算するまでの作業は含まれません。細いデータ型ではなく太いデータ型を使用する場合、代わりに2ギガバイトを見ている可能性があります。単純な例ですが、それでも良い例です。