2012-04-16 15 views
1

私は並列化のための1つの作業ソリューションを持っています。ただし、並列化によって実行時間は非常にわずかに改善されます。私はそれが私が新しい事実から来て、ループ内のいくつかの変数を削除すると思います。私はスタックを作成したいと思いますが、Commandクラスは抽象クラスであり抽象クラスでなければなりません。その問題を回避するために私は何ができますか?どのようにこれらの非常に長いループに費やした時間を改善するか???openMPとの並列化 - スタックまたはヒープ変数

#pragma omp parallel for reduction(+:functionEvaluation) 
for (int i=rowStart;i<rowEnd+1;i++) 
{ 
    Model model_(varModel_); 
    model_.addVariable("i", i); 
    model_.addVariable("j", 1); 
    Command* command_ = formulaCommand->duplicate(&model_); 
    functionEvaluation += command_->execute().toDouble(); 
    delete command_; 
} 

この問題は、他の場所にもある可能性があります。アドバイスを歓迎!!

ありがとうございます。

+0

にはコマンドプールがありますか?コマンドをpreaallocateする? – Anycorn

+0

あなたはもっと正確になりますか? command_は、ループ内に割り当てられたスタックであるmodel_に応じて作成されています。もっと説明したり、1行のコードを書くことができますか?ありがとう!! – octoback

答えて

1

private or firstprivate clausesで遊んでみてください。

#pragmaには...private(varModel, formulaCommand)...などが含まれ、各スレッドにはこれらの変数のコピーがあります。 firstprivateを使用すると、スレッド固有の変数の初期値が初期化されずにコピーされます。これにより、ループの繰り返しごとにインスタンスを変更できるだけで、newdeleteの必要性がなくなります。

多くの詳細を提供していないため、これは必要に応じて機能する場合もあれば、機能しない場合もあります。

+0

あなたはcommand_inの中の引数がa ref to model_である関数の結果であることがわかります。そして、model_は直前の2行で更新されました。それで、私はそれがcommand_のためのfirstprivateと働くことができるとは思わない。 varModel_は実際には最初にプライベートにすることができます。 – octoback

1

私は、割り当てられたメモリを再利用するためのメカニズムを使用するようにしてください。おそらく、オブジェクトのサイズやアライメントがわからないので、「十分に大きい」バッファーでは不十分です。私はあなたのduplicateメソッドが2つの引数を取るようにします.2番目の引数はboost::poolへの参照です。プールオブジェクトが十分大きい場合は、その内部に新しいCommandオブジェクトを構築します。拡張しない場合は、そのオブジェクトを構築します。 boost::poolはあなたのアライメントの問題を処理するので、考慮する必要はありません。この方法では、スレッドごとに動的メモリ割り当てを数回行う必要があります。

ところで、C++で生ポインタを返すのは一般的には良いことではありません。代わりにスマートポインタを使用してください。これは単純なことではありません。しかし、このケースでは、次のようなことがあります。私の提案では、カスタムメモリ管理の下でいくつかやっているからです。それでも、最善の習慣は、ユーザーを台無しにするリスクなしに、あなたの特別なケースを優雅に処理するカスタムスマートポインタを書くことでしょう。あなたはもちろん他の人が好きで、この場合例外を作ることができます:)(私のアドバイスはまだ普通の状況下では成り立ちますが、上記の質問では通常boost::scoped_ptrのようなものを使用してください)