首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从多线程中加速

问从多线程中加速
EN

Stack Overflow用户
提问于 2014-07-04 12:26:38
回答 1查看 110关注 0票数 1

我有一个高度并行的问题。数百个独立的问题需要用相同的功能来解决。每个问题平均需要120毫秒(0.12秒)在一个单一的核心,但有很大的变化,一些极端和罕见的可能需要10倍的时间。每个问题都需要内存,但这是提前分配的。这些问题不需要磁盘I/O,并且它们在运行时不会来回传递任何变量。不过,它们确实访问同一个全局结构的不同部分(数组元素)。

基于其他人的代码,我有C++代码,这是可行的。(未显示结构的全局数组。)它运行20个问题(例如),然后返回。我认为20足以平衡4个核的变化。我看到执行时间已经从大约10点增加到现在的水平。

有一个Win32和一个OpenMP版本,它们在执行时间方面的行为几乎相同。我在一个4核Windows系统上运行这个程序.我在下面包含了一些OpenMP代码,因为它比较短。(我更改了名称等,以使其更加通用,而且我可能犯了错误-它不会单独编译。)

单线程版本的速度大约是2.3倍.因此,如果它需要230秒的单线程,它需要100 s多线程.我感到惊讶的是,速度并没有更接近4,核的数量。

我失望是对的吗?

我能做些什么来接近我的理论预期吗?

代码语言:javascript
复制
int split_bigtask(Inputs  * inputs, Outputs * results)
{
  for (int k = 0; k < MAXNO; k++)
    results->solved[k].value = 0;

  int res;
  #pragma omp parallel shared(inputs, outputs)
  {
    #pragma omp for schedule(dynamic)
    for (int k = 0; k < inputs->no; k++)
    {
      res = bigtask(inputs->values[k], 
                    outputs->solved[k], 
                    omp_get_thread_num()
                   );
    }
  }
  return TRUE;
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-07-04 14:31:23

  1. 我假设在bigtask()中没有同步(很明显,但我仍然会首先检查它)。
  2. 您可能会遇到“脏缓存”问题:如果您操作彼此相近的数据(例如,相同的缓存线!)从多个核开始,每次操作都将缓存线标记为脏(这意味着处理器需要向所有其他进程发出信号,这反过来又涉及同步.)。
  3. 您创建了太多的线程(分配一个线程会造成相当大的开销。因此,为每个核心创建一个线程比为每个内核创建5个线程要高效得多。

我个人认为你有案例2(“大全球阵列”)。

解决问题的方法(如果确实是第2种情况):

  • 将结果写入本地数组,该数组在工作结束后由主线程合并到“大全局数组”中
  • 将全局数组拆分为几个较小的数组(并为每个线程提供其中的一个数组)
  • 确保结构中的记录对齐Cache-Line边界(这有点麻烦,因为缓存行边界对于未来的处理器可能会改变),您可能希望为每个线程创建数组的本地副本(至少对于结果)。
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24574309

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档