- ヒープ割り当ては確かに非常に高価です。
- 時期尚早の最適化は悪いですが、ライブラリが非常に一般的でマトリックスが膨大な場合は、効率的な設計を求めるのが早すぎるとは限りません。結局のところ、多くの依存関係を累積した後でデザインを変更する必要はありません。
- この問題にはさまざまなレベルで対処できます。たとえば、ヒープ割り当てのコストがメモリアロケータレベル(スレッドごとのメモリプール、たとえば
- )であるのに対し、ヒープ割り当ては高価ですが、1つの巨大な行列を作成するだけで、かなり高価な操作を行うことができます(通常は線形の複雑さまたはそれより悪い)。相対的に言えば、フリーストア上で行列を割り当てることは、必然的に後で行う必要があるものと比較して高価ではない可能性があります。したがって、並べ替えのような関数の全体的なロジックと比較して実際にはかなり安いかもしれません。
今後の可能性として#3を考慮して、コードを自然に書くことをおすすめします。つまり、中間計算のための行列バッファへの参照を取り込まず、一時的なものの作成を加速してください。一時的なものを作り、価値によってそれらを返す。正しさと良い、明確なインターフェイスが最初に来る。
ここでの目標は、あまりにも多くの既存のコードを変更することなく、余計なものとして最適化するための呼吸スペースを与えるマトリックスの作成ポリシー(アロケータまたはその他の手段による)を分離することです。関与する関数の実装の詳細だけを変更するか、行列クラスの実装のみを変更することで可能ならば、デザインを変更せずに自由に最適化することができます。それを可能にする任意の設計は、一般に、効率の観点から完全になるであろう。
警告:あなたは本当にすべてのサイクルを最大限に絞るしたい場合にのみ意図されて、次の。 #4を理解し、自分自身に良いプロファイラを得ることは不可欠です。また、ヒープ割り当てを最適化しようとするよりも、これらの行列アルゴリズムのメモリアクセスパターンを最適化するほうが、おそらくもっとうまくいくでしょう。
メモリ割り当てを最適化する必要がある場合は、スレッドごとのメモリプールのような一般的な方法で最適化することを検討してください。例えば、あなたのマトリックスをオプションのアロケータに入れてもいいかもしれませんが、私はここではオプションで強調しています。そして、私は、まず些細なアロケータの実装で正確さを強調したいと思います。すなわち
:
M1(N、P)各関数内、または むしろ一度、(主にすべてのために)を宣言し 、各機能に渡すためのより良いやり方であります各機能がスクラップスペースとして使用できるバケットの一種。
各機能で一時的にM1を作成します。仲介の結果を計算するためにだけ意味のない行列を作ることをクライアントに要求することを避けるようにしてください。それは、(クライアントが知っているべきではない)細部を隠すために、インタフェースを設計するときにやらなければならないことであるべき最適化の詳細を明らかにするでしょう。
オプションのアロケータのように、これらの一時的なオブジェクトの作成を高速化する必要がある場合は、より一般的な概念に焦点を当ててください。これはstd::set
とのような実用的なデザインでフィット:
std::set<int, std::less<int>, MyFastAllocator<int>> s; // <-- okay
、ほとんどの人はちょうど行うにもかかわらず:あなたのケースでは
std::set<int> s;
、それは単に次のようになります。 M1のmy_matrix(N、P、アロケーション) ;
微妙な違いはありますが、アロケータは、キャッシュされたマトリックスよりもはるかに一般的な概念です。それ以外の場合は、クライアントに意味がありません。ただし、関数がより速く結果を計算するために必要なキャッシュ。一般的なアロケータである必要はありません。あらかじめ割り当てられた行列バッファを行列のコンストラクタに渡すだけでも構いませんが、概念的には、クライアントにとっては少し不透明であるという事実のために、それを分けるのが良いかもしれません。
さらに、この一時的な行列オブジェクトを構築するには、スレッド間で共有しないように注意する必要があります。これは、最適化ルートを実行するとコンセプトを少し一般化したい別の理由です。マトリックスアロケータのようなもっと一般的なものは、スレッドの安全性を考慮に入れることができます。スレッドごとに作成されますが、生の行列オブジェクトはおそらく作成できません。
上記は、インターフェイスの品質を最も重要視する場合にのみ役立ちます。そうでない場合は、アロケータを作成するよりもはるかに単純なのでMatthieuのアドバイスをお勧めしますが、アクセラレータ版をオプションのにすることを重視しています。
があります。メモリの割り当ては高価です。ローカルのallocsで開始し、allocsが高価すぎる場合は変更してください。 – Anycorn
@Anycornのメモリ割り当ては、おそらく500以上の値にアクセスするよりも安価で、百万の値にアクセスするよりも安いです。 –
@ JamesKanze +1ヒープ割り当ての相対効率は、一般的にこれらの操作に比べて些細なことになります。最適化ルートを完全に提案しないように投稿を編集することを考えています。 – stinky472