4

我有一个关于 Microsoft PPL 库和一般并行编程的问题。我正在使用 FFTW 执行大量(100,000)64 x 64 x 64 FFT 和逆 FFT。在我当前的实现中,我使用并行 for 循环并在循环内分配存储数组。我注意到在这些情况下,我的 CPU 使用率最高只有 60-70%。(请注意,这仍然比我测试过的 FFTW 提供的内置线程 FFT 更好地利用)。由于我使用的是 fftw_malloc,是否有可能发生过度锁定而阻止完全使用?

鉴于此,是否建议在主处理循环之前为每个线程预先分配存储数组,这样循环本身就不需要锁?如果是这样,MSFT PPL 库怎么可能做到这一点?我之前一直在使用 OpenMP,在这种情况下,使用提供的函数获取线程 ID 很简单。但是,我在 PPL 文档中没有看到类似的功能。

4

2 回答 2

2

我只是在回答这个问题,因为还没有人发布任何内容。

如果需要大量锁定,Mutex(e) 可能会对性能造成严重破坏。此外,如果需要大量内存(重新)分配,这也会降低性能并将其限制为内存带宽。就像您说的那样,稍后线程操作的预分配可能很有用。但是,这要求您有一个固定的线程数,并且您将工作负载均衡地分布在所有线程上。

关于 PPL thread_id 函数,我只能说 Intel-TBB,但它应该与 PPL 非常相似。TBB - 我也想 PPL - 不是直接谈论线程,而是他们谈论任务,TBB 的目的是将这些底层细节从用户那里抽象出来,因此它不提供 thread_id 函数。

于 2012-04-04T08:39:36.867 回答
1

使用 PPL,我在一个应用程序中获得了良好的性能,该应用程序通过使用 aConcurrency::combinable来保存包含每个线程分配的内存的结构来进行大量分配。

事实上,您不必预先分配,您可以检查可组合变量的值,->local()如果它为空,则分配它。下次调用这个线程时,它已经被分配了。

当然,当所有任务完成后,你必须释放内存,这可以使用:使用类似的东西:

combine_each([](MyPtr* p){ delete p; });
于 2012-11-04T16:34:27.620 回答