6

charCで小さな整数を使用することに不利な点はありますか? 占有/メモリの利点以外に利点はありますか?

特に、プロセッサは ( / )charよりも良いか悪いかで整数演算に対処する可能性がありますか?longshortint

これはプロセッサ/システム/コンパイラ固有であることはわかっていますが、一般的なケース、または少なくとも、現在取り組んでいるシステムである 32 ビット Windows と Solaris の一般的なケースでの回答を期待しています。 . また、オーバーフロー/ラップアラウンドの問題などは既に対処されていると想定しています。

stdint.h更新: Visual Studio 6.0 には、Christoph の提案どおりの機能は実際にはありません。少数のスタック ループを使用した Windows (VS 6.0、デバッグ ビルド、32 ビット) での小さなベンチマークでは、intlong同様のパフォーマンスが得られ、 char. Linux で gcc を使用して同じテストを実行すると、同じように pegsintと同様に実行longされ、どちらも よりも高速ですcharが、違いはそれほど顕著ではありません。

補足として、私はあまり時間をかけて調べていませんが、私が見つけた VS 6.0の最初の実装(stdint.hウィキペディア経由) は、少なくとも私のテストでは遅いように見えますが、uint_fast8_tとして定義されています。unsigned charしたがって、クリストフが正しく示唆したように、この話の教訓は次のとおりです。

4

6 に答える 6

12

C99は、この問題を解決するために、いわゆる「最速」の最小幅整数型を追加しました。関心のある範囲の場合、タイプはとになります。これは、にありint_fast8_tます。uint_fast8_tstdint.h

パフォーマンスが向上しない可能性があることに注意してください(メモリ消費量の増加により、処理速度が低下する場合もあります)。いつものように、ベンチマーク!何が機能するかについて、欠陥のある可能性のある仮定に基づいて、時期尚早に、または単に最適化しないでください。

于 2009-12-06T13:02:51.733 に答える
6

最初の問題は、plaincharが符号付きであるか符号なしであるかが C 標準で定義されていないことです。そのため、移植可能な唯一の範囲は 0 から 127 までです。

それ以外は、一般intに、アーキテクチャのネイティブ ワード サイズに対応する型であると想定されています (もちろん、これは何によっても強制されません)。これは、最高の演算パフォーマンスを持つ型になりがちですが、それはあなたが言えるすべてです。

よりも狭いオペランドは、とにかく式の評価まで、または評価中にint拡張されることに注意してください。intunsigned int

于 2009-12-06T12:15:52.843 に答える
3

私が考えることができるもう1つの欠点は、(私が知る限り)「最新の」プロセッサはすべての計算を「完全な」整数、通常は32ビットで行うことです。したがって、a を処理するということは、char通常、メモリから 1 バイトを引き出し、レジスタに転送する際に 0 を埋め、それを使って何かを行い、結果の最下位ビットのみをメモリに戻すことを意味します。特にcharが適切な境界に揃えられていない場合、このメモリ アクセスを実行するにはさらに多くの作業が必要になります。

charfor の使用は、多数の数値 (つまり、大きな配列) があり、スペースを節約する必要がintある場合にのみ役立ちます。

于 2009-12-06T12:20:33.863 に答える
3

char の算術演算は、int の算術演算と同じレジスタを使用して実際に実行されることはほぼ確実です。例えば:

char c1 = 1;
char c2 = c1 + 2;

この追加は、VC++ で次のようにコンパイルされます。

00401030   movsx       eax,byte ptr [ebp-4]
00401034   add         eax,2
00401037   mov         byte ptr [ebp-0Ch],al

ここで、eax は 32 ビット レジスタです。

したがって、算術パフォーマンスに関しては、int よりも char を使用する利点はありません。

于 2009-12-06T12:27:49.853 に答える
2

内部的には、プロセッサは通常、機械語に対して算術演算を実行します。つまり、他のタイプの計算が実行される場合、計算自体には同じ時間がかかりますが、使用可能な命令セットによっては、入力を読み取り、計算結果をターゲット タイプに変換するために余分な作業が必要になる場合があります (例:符号拡張/ゼロ フィリング、非整列メモリ アクセスを回避するためのシフト/マスキングなど)。

これが、C が型と演算を C と同じように定義する理由です。 のサイズはint標準で義務付けられておらず、コンパイラの作成者はそれを機械語に対応させることができ、式の評価はより小さな整数型を にプロモートするように定義されてintおり、数が大幅に削減されています。結果を何らかのターゲットタイプに強制する必要があるポイントの。

整数値を保存するために使用する正当な理由charは、スペースが本当に重要な場合 (思ったほど頻繁ではない) と、データをマーシャリングする外部データ形式/プロトコルを記述する場合です。を使用すると、パフォーマンスがわずかに低下することが予想charされます。特に、Cell SPU などのハードウェアでは、マシン ワード サイズのメモリ アクセスしか利用できないため、メモリ内の char にアクセスするには、いくつかのシフトとマスクが必要になります。

于 2009-12-06T12:22:03.110 に答える
0

私が見る主な短所は、あなたのコードが、何か他のことを意味する値に対してあることを意味する型を使用していることです。たとえば、メンテナンスの問題である可能性のあるセマンティックの問題があります。あなたがそれをしたなら、私はおそらくそれを型定義することをお勧めします:

typedef char REALLYSHORT;

そうすれば、A) 何をしているかがより明確になり、B) 問題が発生した場合に簡単に (たとえば、1 か所だけ) 変更できます。

を使用しない本当に正当な理由はありますかint?

于 2009-12-06T12:17:01.047 に答える