4

カスタム ビット フィールドを配置できる 96 ビット長の構造体が必要です。フィールドの長さはいたるところにあります8, 3, 26, 56. これらの正確な長さを維持することが重要です (1 つの例外を除き、以下を参照してください)。

データを 1 つのコンパクトなフィールドに連結する方法は数多くstd::bitsetありstructますint。でも:

  • 操作は非常に高速に行われる必要があるため、このbitsetアプローチには問題があります。bitset は、1 つのアトミック操作で、(x..y)範囲全体から範囲を即座に設定する方法を提供しません。(0..96)個々のビットを設定するためにループするつもりなら、いまいましい。

  • この長さの制限のため、このstructアプローチには問題があります。

  • 十分な長さがないため、このintアプローチには問題があります。int64_tもちろん、int32_tこれと一緒に使用できますが、以下を参照してください。

明らかな解決策の 1 つは、56 + 8フィールドをに入れint64_t、残りを に入れることint32_tです。ここでの問題は、56-long フィールドだけが実際には開発の後半で縮小される可能性があるということです。これはint64_t、 にいくつかの32 - (26 + 3) = 3スペア ビットとint32_t.

これらを(コードの観点から)できるだけコンパクトに格納しながら、(とは異なりstd::bitset)マスキングによって広い領域にアクセスできる方法はありますか?

4

3 に答える 3

3

わかりました、ここに古典的なサイズと速度の状況があります。私は尋ねようとしています、これはすべてのビットが重要な状況ですか? いくつかのビットが完全に使用されていない場合、それはそれほど大きな問題ですか? 私のCコーダーは、3つの32ビット値の配列、または64ビット、32ビット値のアプローチのいずれかを好みます。私のオプティマイザーは、96 ビットのデータ構造が完全にキャッシュに適しているわけではなく、むしろ 128 ビットにパディングされるか、少なくとも 4 バイトの境界を越えてできるだけアクセスされないようにするという事実を好まない。

ターゲット プラットフォームに応じて、64 ビット値を使用すると、56 ビット エントリ全体を 1 つの命令でマスキングできますが、32 ビット バージョンでは少なくとも 2 つの操作が必要になります。しかし、その値を 32 ビット (または最大 64 ビット) まで下げることができれば、64 ビット アドレス境界でその 64 ビット値を保持する限り、マスキングはまったく行われず、全速力で進みます。一部のターゲットでは、ペナルティでデータの非整列にアクセスできますが、他のターゲットでは実際に例外がスローされます。

最も安全な方法は、3 つの 32 ビット値の配列です。アラインメントは保証され、ビットフィールドが 32 ビットの境界にまたがらない限り、数学を単純に保つことができ、最も移植性が高くなります。境界をまたぐ必要がある場合は、追加のマスキングとシフトで速度が低下します。しかし、これが大きな問題です。このデータへのアクセスが速度の問題であると本当に確信していますか? これがボトルネックであることを示すプロファイルを手元に持っていますか? そうでない場合は、ビットフィールド C++ ソリューションを使用して、それを良いと呼びます。より安全で使いやすいことは、ほとんど常に勝利です。

于 2011-11-15T16:34:55.580 に答える
2
uint32_t bits[3];

そこに、96ビット、PODタイプで、好きなだけいじることができます。

もちろん、速度が必要な場合は、単一のビット フィールドを使用しない方が速度が向上する可能性が非常に高くなります。しかし、このレベルでデータをパックstd::bitsetたい場合で、インターフェイスがあまりにも制約的である場合は、単純な配列を使用することをお勧めします。

于 2011-11-15T14:01:11.020 に答える
2

私のコメントで言ったように、 use bitset、必要なすべての二項演算子があります。たとえば、次のようになります。

std::bitset<96> foo(0xFF1); // set bit 1 & bits 5-12

// to test
std::bitset<96> mask(0xFF0); // are bits 5-12 set?
// test, yes the global & operator will create a temporary
if ((mask & foo) == mask)
{
  // do stuff...
}
于 2011-11-15T14:10:33.200 に答える