【问题标题】:parallelization with openMP - stack or heap variables使用 openMP 并行化 - 堆栈或堆变量
【发布时间】:2012-04-27 19:50:04
【问题描述】:

我有一个可行的并行化解决方案。然而,并行化对执行时间的改善非常非常轻微。我认为这是因为我在循环中新建并删除了一些变量。我希望它是堆栈创建的,但是 Command 类是抽象的,并且必须保持抽象。我能做些什么来解决这个问题?如何减少花在这些非常长的循环上的时间???

#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_;
}

问题也可能出在其他地方!欢迎咨询!!

感谢和问候。

【问题讨论】:

  • 有一个命令池?预分配命令?
  • 你能更精确一点吗?您会看到 command_ 是根据 model_ 创建的,它是在循环内分配的堆栈。你能解释更多,甚至写一两行代码吗?谢谢!!

标签: c++ multithreading stack openmp


【解决方案1】:

您可能想玩private or firstprivate clauses

您的#pragma 将包括...private(varModel, formulaCommand)... 或类似的,然后每个线程将有自己的这些变量的副本。使用firstprivate 将确保线程特定变量具有复制的初始值,而不是未初始化。这将消除对newdelete 的需要,假设您可以只修改每次循环迭代的实例。

这可能会或可能不会按预期工作,因为您没有提供很多细节。

【讨论】:

  • 您会看到 command_ in loop 是一个函数的结果,该函数的参数是对 model_ 的引用。而model_在前两行刚刚更新。所以我不相信它可以与firstprivate for command_一起使用。 varModel_ 确实可以是第一个私有的。
【解决方案2】:

我认为您应该尝试使用一种机制来重用分配的内存。您可能不知道即将到来的Command 对象的大小和对齐方式,因此“足够大”的缓冲区是不够的。我会让你的duplicate 方法接受两个参数,第二个是对boost::pool 的引用。如果池对象足够大,只需在其中构建新的Command 对象,如果它没有扩展它,则构建它。 boost::pool 将为您处理对齐问题,因此您不必考虑它。这样,您只需为每个线程执行几次动态内存分配。

顺便说一句,在 C++ 中返回原始指针通常不是一个好习惯。改用智能指针,没有任何但更好的方式......好吧,在这种情况下有一个但是:),因为根据我的建议,你会在引擎盖下做一些自定义内存管理。尽管如此,最好的做法是编写一个自定义智能指针,它可以优雅地处理您的特殊情况,而不会冒着用户搞砸的风险。你当然可以像其他人一样做,在这种情况下例外:)(我的建议在正常情况下仍然有效,f.x.在上面的问题中,你通常应该使用boost::scoped_ptr之类的东西)

【讨论】:

    猜你喜欢
    • 2019-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-09
    • 1970-01-01
    • 2018-06-16
    • 2011-04-28
    • 1970-01-01
    相关资源
    最近更新 更多