【发布时间】:2016-12-22 20:20:59
【问题描述】:
有什么方法可以限制 TPL 数据流限制的性能下降?
我有一个复杂的组件管道,并试图限制所需的内存需求。我从多个文件中并行读取,管道中的组件可能会从这些文件的随机部分执行一些附加读取,其余组件执行 CPU 绑定操作。
我使用通用测试方法将性能测试台简化为这些测试。
private void TPLPerformaceTest(int generateNumbers,
ExecutionDataflowBlockOptions transformBlockOptions)
{
var transformBlock = new TransformBlock<int, int>(i => i, transformBlockOptions);
var storedCount = 0;
var generatedCount = 0;
var store = new ActionBlock<int>(i => Interlocked.Increment(ref storedCount));
transformBlock.LinkTo(store);
transformBlock.Completion.ContinueWith(_ => store.Complete());
for (int i = 0; i < generateNumbers; i++)
{
transformBlock.SendAsync(i).Wait(); //To ensure delivery
Interlocked.Increment(ref generatedCount);
}
transformBlock.Complete();
store.Completion.Wait();
Assert.IsTrue(generatedCount == generateNumbers);
Assert.IsTrue(storedCount == generateNumbers);
}
第一个没有限制。在我的 CPU 上,大约需要 12 秒 才能完成,消耗大约 800MB 的 RAM,平均 CPU 利用率约为 35%。
[Test]
public void TPLPerformaceUnlimitedTest()
{
var generateNumbers = 100_000_000;
this.TPLPerformaceTest(generateNumbers,new ExecutionDataflowBlockOptions());
}
第二个测试,只是将BoundedCapacity设置为int.MaxValue,因此完全没有限制,需要20-30s完成,消耗2.1GB strong> 的 RAM 和平均 CPU 利用率约为 50%。根据手册,BoundedCapacity 应该默认设置为 int.MaxValue,所以我看不出性能下降的原因。
[Test]
[Sequential]
public void TPLPerformaceBounedCapacityTest()
{
var generateNumbers = 100_000_000;
this.TPLPerformaceTest(generateNumbers,new ExecutionDataflowBlockOptions()
{ BoundedCapacity = Int32.MaxValue });
}
第三个测试限制BoundedCapacity to generateNumbers / 1000,即100,000。它需要 60 秒才能完成并消耗 450MB 的 RAM,平均 CPU 利用率约为 60%。
[Test]
[Sequential]
public void TPLPerformaceBounedCapacityTenthTest()
{
var generateNumbers = 100_000_000;
this.TPLPerformaceTest(generateNumbers,new ExecutionDataflowBlockOptions()
{ BoundedCapacity = generateNumbers / 1000 });
}
第四次测试将MaxDegreeOfParallelism限制为-1,根据手册没有限制。它消耗了 27GB 的 RAM,平均 CPU 使用率约为 85%,并且在 5 分钟内还没有完成。
[Test]
[Sequential]
public void TPLPerformaceMaxDegreeOfParallelismTest()
{
var generateNumbers = 100_000_000;
this.TPLPerformaceTest(generateNumbers, new ExecutionDataflowBlockOptions()
{ MaxDegreeOfParallelism = -1 });
}
所有方法似乎都很难影响性能,并且由于我的合理预期而表现不佳。
【问题讨论】:
标签: c# performance parallel-processing performance-testing tpl-dataflow