我正在制作 C# 软件来实现 RFC 1951“Deflate”压缩。在选择 block 边界以最大化压缩时,有机会并行计算两个备选 block 选择的大小,以提高性能(这是相当长的计算,涉及霍夫曼码的计算)。
这是非并行版本:
int bits2 = b2.GetBits();
int bits3 = b3.GetBits();
这是并行版本:
Task<int> t2 = Task<int>.Factory.StartNew( () => { return b2.GetBits(); } );
int bits3 = b3.GetBits(), bits2 = t2.Result;
然而并行版本实际上运行得更慢,我不明白为什么。如果相关,处理器是 Intel Core i7-6700HQ。完整代码在这里:https://github.com/georgebarwood/pdf/blob/master/Deflator.cs
为什么并行版本运行得更慢而不是更快,我是否犯了错误,我可以做些什么来使并行版本比非并行版本运行得更快?
最佳答案
如果我在我的计算机上运行您的 GetBits
方法,它的平均运行时间不到 3µs。并行运行代码有一些开销。事实上,调用 Task.Factory.StartNew
在调用方也需要 2 到 3 微秒(我没有测量任务实际开始执行之前的时间)。因此,在您的情况下,开销会抵消潜在 yield 。
这是使算法高效并行运行的难点之一:您需要确保工作单元足够大以抵消引入的开销。
关于c# - 为什么使用两个任务执行两个长计算会降低性能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54380115/