我对Microsoft PPL库以及一般的并行编程有疑问。我正在使用FFTW执行64 x 64 x 64 FFT和反FFT的大集(100,000)。在我当前的实现中,我使用并行for循环并在循环中分配存储阵列。我注意到在这些情况下我的CPU使用率仅为60-70%。 (注意,这仍然比我测试的FFTW提供的内置线程FFT更好的利用率)。由于我使用的是fftw_malloc,是否可能发生过度锁定而导致无法完全使用?
鉴于此,建议在主处理循环之前为每个线程预分配存储数组,因此循环内部不需要锁定吗?如果是这样,MSFT PPL库如何实现?我之前一直在使用OpenMP,在这种情况下,使用提供的函数获取线程ID非常简单。但是,我没有在PPL文档中看到类似的功能。
答案 0 :(得分:2)
我只是回答这个问题,因为还没有人发布任何内容。
如果需要大量锁定,Mutex(e)可能会对性能造成严重破坏。此外,如果需要大量内存(重新)分配,这也会降低性能并将其限制为内存带宽。就像你说的那样,后期线程运行的预分配可能很有用。但是,这需要您拥有固定的线程数,并且您可以在所有线程上平衡您的工作负载。关于PPL thread_id函数,我只能谈论Intel-TBB,但它应该与PPL非常类似。 TBB - 我想也是PPL - 不直接谈论线程,而是谈论任务,TBB的目的是将这些底层细节抽象出用户,因此它不提供thread_id函数。
答案 1 :(得分:0)
使用PPL我通过使用Concurrency::combinable
来保存包含每个线程分配的内存的结构来执行大量分配的应用程序具有良好的性能。
实际上,您不必预先分配,您可以使用->local()
检查可组合变量的值,如果它为null,则分配它。下次调用此线程时,它将被分配。
当完成所有任务时,你必须释放内存,这可以通过以下方式完成: 有类似的东西:
combine_each([](MyPtr* p){ delete p; });