我正在使用Concurrency::parallel_for()
Visual Studio 2010 的并行模式库 (PPL) 来处理一组索引任务(通常,索引集远大于可以同时运行的线程数)。每个任务,在进行冗长的计算之前,首先从共享资源管理器请求一个私有的工作存储资源(以防:查看任务特定的内存映射文件,但我认为如果每个任务的故事情节是相同的从共享堆请求私有内存分配)。
共享资源管理器的使用与 a 同步,Concurrency::critical_section
这里问题开始了:如果第一个线程/任务在临界区并且第二个任务发出请求,它必须等到第一个任务的请求被处理。PPL 显然会想:嘿,这个线程正在等待,还有更多任务要做,因此创建了另一个线程,导致多达 870 个线程主要在同一个资源管理器处等待。
现在,由于处理资源请求只是整个任务的一小部分,我想告诉 PPL 在该部分保持其马匹,任何等待或协作块都不应该导致新线程从指定部分开始工作线程,我的问题是:我是否以及如何阻止特定线程部分创建新线程,即使它合作阻塞。我不介意在线程处理路径下方的其他块中创建新线程,但不会超过 2*(超)核心数。
到目前为止我考虑过的替代方案:
排队任务并从有限数量的线程处理队列。问题:我希望 PPL 的 parallel_for 能够自行完成。
定义一个
Concurrency::combinable<Resource> resourceSet
;Concurrency::parallel_for
和初始化一次resourceSet.local()
以减少资源请求的数量(通过重用资源)到线程的数量(应该小于任务的数量)。问题:此优化不会阻止多余的线程创建。parallel_for
为循环外的每个任务预先分配所需的资源。问题:这将请求过多的系统资源,而将资源量限制为线程/内核的数量是可以的(如果没有爆炸的话)。
我阅读了http://msdn.microsoft.com/en-us/library/ff601930.aspx的“不要在并行循环中重复阻塞”部分,但遵循此处的建议将导致根本没有并行线程。