2012-04-16 50 views
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

有一個命令池?預分配命令? – Anycorn 2012-04-16 13:18:03

+0

你能更精確嗎?您會看到command_是根據model_創建的,該model_是在循環內部分配的堆棧。你能解釋一下,還是寫一行或兩行代碼?謝謝!! – octoback 2012-04-16 13:27:19

回答

1

你可能想玩private or firstprivate clauses

您的#pragma將包括...private(varModel, formulaCommand)...或類似的,然後每個線程將擁有自己的這些變量的副本。使用firstprivate將確保線程特定的變量具有複製的初始值,而不是未初始化的。假設您可以修改每個循環迭代的實例,這將消除newdelete的需要。

這可能會或可能不會按要求工作,因爲您沒有提供很多細節。

+0

您會看到command_in循環是一個函數的結果,該函數的參數爲​​ref到model_。並且model_剛剛在前面兩行中進行了更新。所以我不相信它可以用於command_的firstprivate。 varModel_確實可以是firstprivate。 – octoback 2012-04-16 15:02:06

1

我想你應該嘗試使用一種機制來重新使用分配的內存。您可能不知道大小,也不知道Command對象的對齊方式,因此「足夠大」的緩衝區不足以滿足要求。我會讓你的duplicate方法有兩個參數,第二個參考是boost::pool。如果池對象足夠大,只需構建其中的新對象Command,如果它沒有展開它並構造它。 boost::pool將爲您處理對齊問題,因此您不必考慮它。這樣,你必須每個線程只做幾次動態內存分配。

順便說一下,在C++中返回原始指針一般不是很好的做法。使用智能指針代替它,只是沒有任何buts而言更好......嗯,在這種情況下有一個:),因爲在我的建議下,你會在引導下進行一些自定義內存管理。儘管如此,最好的做法是編寫一個自定義的智能指針,它可以優雅地處理您的特殊情況,而不會冒用戶冒險。你當然可以像其他人一樣做,並在這種情況下作出例外:)(我的建議仍然在正常情況下,雖然,在上面的問題f.x.,你通常應該使用像boost::scoped_ptr