24

あらゆるタイプの可能な最大の配置を決定するためのポータブルな方法はありますか?

たとえば、x86では、SSE命令には16バイトの整列が必要ですが、私が知る限り、それ以上の命令は必要ないため、どのタイプでも16バイトに整列されたバッファーに安全に格納できます。

任意のタイプのオブジェクトを書き込むことができるバッファー(char配列など)を作成する必要があるため、整列するバッファーの先頭に依存できる必要があります。

他のすべてが失敗した場合、char配列を割り当てるとnew最大の配置が保証されることはわかっていますが、TR1 / C ++ 0xテンプレートalignment_ofaligned_storageを使用すると、バッファーをインプレースで作成できるかどうか疑問に思います。動的に割り当てられた配列の追加のポインター間接参照を必要とするのではなく、クラス。

アイデア?

有界型のセットの最大アラインメントを決定するためのオプションがたくさんあることを理解しています。和集合、またはalignment_ofTR1からだけですが、私の問題は、型のセットが有界でないことです。どのオブジェクトをバッファに保存する必要があるかを事前に知りません。

4

6 に答える 6

15

C++11ではヘッダーで定義されているstd::max_align_t cstddefはPOD型であり、その配置要件は少なくともすべてのスカラー型と同じくらい厳密(大きい)です。

新しいalignof演算子を使用すると、次のように簡単になります。alignof(std::max_align_t)

于 2013-04-17T23:06:24.443 に答える
11

C ++ 0xでは、のAlignテンプレートパラメータにstd::aligned_storage<Len, Align>は「default-alignment」のデフォルト引数があり、これは(N3225§20.7.6.6表56)として定義されています。

default-alignmentの値は、サイズが。以下のC++オブジェクトタイプの最も厳しいアライメント要件ですLen

SSEタイプが「C++オブジェクトタイプ」と見なされるかどうかは明確ではありません。

デフォルトの引数はTR1の一部ではありませんでしたaligned_storage。C++0x用に追加されました。

于 2010-12-30T16:42:33.103 に答える
7

残念ながら、最大位置合わせを確実にすることは、本来あるべきよりもはるかに困難であり、AFAIKの保証された解決策はありません。GotWブログ(Fast Pimplの記事)から:

union max_align {
  short       dummy0;
  long        dummy1;
  double      dummy2;
  long double dummy3;
  void*       dummy4;
  /*...and pointers to functions, pointers to
       member functions, pointers to member data,
       pointers to classes, eye of newt, ...*/
};

union {
  max_align m;
  char x_[sizeofx];
};

これは完全に移植可能であることが保証されているわけではありませんが、これが期待どおりに機能しないシステムがほとんどないかまったくないため、実際には十分に近いです。

それは私がこれについて知っている最も近い「ハック」についてです。

超高速割り当てのために私が個人的に使用した別のアプローチがあります。それは悪いことですが、私は速度が品質の最大の尺度の1つであるレイトレーシング分野で働いており、コードを毎日プロファイリングしています。これには、ローカルスタックのように機能する事前に割り当てられたメモリを備えたヒープアロケータの使用が含まれます(割り当て時にポインタをインクリメントし、割り当て解除時に1つデクリメントします)。

特にニキビに使っています。ただし、アロケータを持っているだけでは十分ではありません。このようなアロケータが機能するには、クラスFooのメモリがコンストラクタで割り当てられ、同じメモリがデストラクタでのみ割り当て解除され、Foo自体がスタック上に作成されると想定する必要があります。安全を確保するために、クラスの「this」ポインタがローカルスタック上にあるかどうかを確認して、超高速ヒープベースのスタックアロケータを使用できるかどうかを判断する関数が必要でした。そのためには、OS固有のソリューションを調査する必要がありました。Win32 / Win64用のTIBとTEBを使用し、同僚がLinuxとMacOSX用のソリューションを見つけました。

その結果、スタック範囲、アライメント要件を検出するためのOS固有の方法を調査し、多くのテストとプロファイリングを行った後、約ではなく、ティックカウンターベンチマークに従って4クロックサイクルでメモリを割り当てることができるアロケータができました。新しいmalloc/operatorの場合は400サイクル(テストにはスレッドの競合が含まれていたため、mallocはシングルスレッドの場合よりも少し速くなる可能性があります(おそらく数百サイクル))。スレッドごとのヒープスタックを追加し、使用されているスレッドを検出して、時間を約12サイクルに増やしましたが、クライアントはスレッドアロケータを追跡して4サイクルの割り当てを取得できます。マップからメモリ割り当てベースのホットスポットを一掃しました。

このような問題をすべて解決する必要はありませんが、高速アロケータを作成する方が、max_alignここにあるようなものよりも簡単で一般的に適用できる場合があります(例:実行時に割り当て/割り当て解除するメモリの量を決定できるようにする)。max_align使い方は簡単ですが、メモリ割り当ての速度を求めている場合(そして、コードのプロファイルを作成し、malloc / free / operator new / deleteにホットスポットがあり、主要な貢献者が自分で制御できるコードにあると仮定した場合)、独自のアロケータを作成することで、実際に違いを生むことができます。

于 2010-06-27T09:43:52.913 に答える
5

すべてのコンパイラがあらゆる場所のすべてのアーキテクチャを忠実にサポートすることを約束したいくつかのmaximally_aligned_tタイプを除いて、コンパイル時にこれをどのように解決できるかわかりません。あなたが言うように、潜在的なタイプのセットは無制限です。余分なポインターの間接参照は本当に大したことですか?

于 2009-10-06T19:59:06.740 に答える
1

アラインされたメモリの割り当ては、見た目よりも注意が必要です。たとえば、アラインされたメモリ割り当ての実装を参照してください。

于 2009-10-06T20:00:03.290 に答える
-2

これが私が使っているものです。これに加えて、メモリを割り当てる場合、max_alignment以上の長さのcharのnew()された配列がmax_alignmentに整列されるため、その配列へのインデックスを使用して整列されたアドレスを取得できます。

enum {
            max_alignment = boost::mpl::deref<
                boost::mpl::max_element<
                        boost::mpl::vector<
                            boost::mpl::int_<boost::alignment_of<signed char>::value>::type,
                            boost::mpl::int_<boost::alignment_of<short int>::value>::type,
                            boost::mpl::int_<boost::alignment_of<int>::value>::type,                                boost::mpl::int_<boost::alignment_of<long int>::value>::type,
                            boost::mpl::int_<boost::alignment_of<float>::value>::type,
                            boost::mpl::int_<boost::alignment_of<double>::value>::type,
                            boost::mpl::int_<boost::alignment_of<long double>::value>::type,
                            boost::mpl::int_<boost::alignment_of<void*>::value>::type
                        >::type
                    >::type
                >::type::value
            };
        }
于 2012-03-20T22:46:53.313 に答える