与openMP并行化 - 堆栈或堆变量

问题描述:

我有一个并行化的工作解决方案。但是,执行时间通过并行化得到很小的改进。我认为它来自我新的事实,并删除循环中的一些变量。我希望它是堆栈创建的,但是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

你可能想玩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

我想你应该尝试使用一种机制来重新使用分配的内存。您可能不知道大小,也不知道Command对象的对齐方式,因此“足够大”的缓冲区不足以满足要求。我会让你的duplicate方法有两个参数,第二个参考是boost::pool。如果池对象足够大,只需构建其中的新对象Command,如果它没有展开它并构造它。 boost::pool将为您处理对齐问题,因此您不必考虑它。这样,你必须每个线程只做几次动态内存分配。

顺便说一下,在C++中返回原始指针一般不是很好的做法。使用智能指针代替它,只是没有任何buts而言更好......嗯,在这种情况下有一个:),因为在我的建议下,你会在引导下进行一些自定义内存管理。尽管如此,最好的做法是编写一个自定义的智能指针,它可以优雅地处理您的特殊情况,而不会冒用户冒险。你当然可以像其他人一样做,并在这种情况下作出例外:)(我的建议仍然在正常情况下,虽然,在上面的问题f.x.,你通常应该使用像boost::scoped_ptr