Ang*_*ker 2 .net c# multithreading
我在.NET 4.51,C#Web服务上有一个工作单元,需要100毫秒.通常,Web请求包含10个单位的工作.因此,通过for循环顺序处理它需要大约一秒钟.
foreach (var u in unitsOfWork) {
Run(u);
}
Run Code Online (Sandbox Code Playgroud)
由于该盒子有12个CPU,我决定将工作拆分并同时运行,希望获得性能提升.我Parallel.ForEach以前做的工作:
Parallel.ForEach(unitsOfWork,u => {
Run(u);
});
Run Code Online (Sandbox Code Playgroud)
令我惊讶的是,每个工作单元平均花费425毫秒.所以最后我节省了约500毫秒的请求.看起来我应该能够获得更好的性能,看看这个盒子有12个CPU ......我错过了一些简单的东西吗?
我寻找任何共享的东西(可能会把它拿起来),但什么都没找到......所以我试着试验.我发出了2个工作单元的请求,每个工作大约需要125毫秒.有3个请求,每个单元需要150毫秒,依此类推.随后每个单位的数量,罚款约25至30毫秒.
所以要么我做错了什么......或者多线程只有固有的开销(没有意识到它是如此之大).
PS我也尝试用Thread.Join替换Parallel.For - 结果相同.

T(1)单线程速度在哪里,n是CPU的数量,B是不能完成的任务的百分比序列化.通过该公式,启动新任务的开销被认为是零.
如果您的任务完全可并行化,B则为零,并且您将在1/12的时间内完成任务.但是,即便是谦虚B的20%,也会将12个CPU的最高潜在加速限制为仅3.75倍 - 略高于理论极限12倍的三分之一.
无法并行化的事情包括对共享资源的序列化访问,例如I/O以及等待其他任务的完成.
处理高速缓存争用会使事情变得更糟:当并发任务访问不同的内存区域时,它们会将硬件高速缓存中的相互数据踢出,这相当于B上面公式中的增加.
总而言之,您的观察并不罕见,并且您没有遗漏任何东西.实现理论上可能的sppedup非常困难,实现的实际加速取决于并行程序需要运行的任务.