具有PPL和并行内存分配的线程ID

Thread IDs with PPL and Parallel Memory Allocation

本文关键字:线程 ID 分配 内存 PPL 并行 具有      更新时间:2023-10-16

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

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

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

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

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

使用PPL,我对一个应用程序有很好的性能,该应用程序通过使用Concurrency::combinable来保存包含每个线程分配的内存的结构来进行大量分配。

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

当然,当所有任务都完成时,您必须释放内存,可以使用以下方法完成:比如:

combine_each([](MyPtr* p){ delete p; });