目录
文章系列
- 统一并发 I - 简介
- 统一并发 II - 基准测试方法
- 统一并发 III - 跨基准测试
- 统一并发 IV - 跨平台(.NET Core 2.1 / .NET Standard 2.0)
介绍
今天,我要宣布统一并发要跨平台了!
统一并发现在符合.Net Standard 2.0,确保在.NET 4.7+和.NET Core 2.0+、Mono 5.4+中访问。
.NET世界中最近的跨平台开发似乎势不可挡,从.Net Standard 2.0开始,该平台的采用率似乎在开源和商业领域的各个领域都得到了加速。这是统一并发成为跨平台的巨大动力。只要有可能,我仍然打算保持.Net 4.6版本的活力,但主要的开发已经转移到.Net Standard项目。
.Net Standard 2.0下的推送库 GreenSuperGreen(包含统一并发)还需要完整的基准测试和跨基准测试库进行相同的更新,为在.NET/.NetCore和Mono上运行基准测试、跨基准测试和跨平台基准测试提供机会。做Linux基准测试也会很有趣,但目前的基准测试依赖于PerformanceCounters平台(Windows),这个问题的解决方案似乎是.Net Standard未来版本的一个悬而未决的问题。
开始使用的所有已实现同步原语的示例都包含在此处作为.NetCore 2.1下的单元测试项目:
统一并发框架在开源实现GreenSuperGreen库上可用的GitHub和的NuGet。
.NET 4.6
NetStandard 2.0
- http://www.nuget.org/packages/GreenSuperGreen.NetStandard/
- http://www.nuget.org/packages/GreenSuperGreen.NetStandard.Test/
- http://www.nuget.org/packages/GreenSuperGreen.Benchmarking.NetStandard/
NetCore 2.1
Net 4.7.2
更多同步原语
现在可以使用另外3个同步原语,另外1个仅用于内部(基准测试目的)。
AsyncSemaphoreSlimLockUC : IAsyncLockUC
SemaphoreSlim基于WaitAsync/Release的锁,似乎在FIFO风格、公平访问中表现良好。
性能方面类似于AsyncLockUC.
SemaphoreSlimLockUC : ILockUC
基于SemaphoreSlim Wait/Release的锁结合了一种混合方法和原子指令,这种方法在FIFO风格中表现不佳,不公平的访问会导致线程停顿!
SemaphoreLockUC : ILockUC
基于信号量WaitOne/Release的锁,依赖操作系统,windows上大致FIFO,不保证公平性。
MutexLockUC : ILockUC——内部,特定用途,仅基准测试
此同步原语不可访问,仅适用于预定义的基准测试项目,因为它在进入和退出调用时需要线程关联,统一并发的设计不支持这一点,但对于基准测试而言,它是可维护的,并且对于收集数据很有趣。
.NET核心加速
根据来自Microsoft、外部资源和技术社区的报告,.NET Core可以加速现有代码库已成为常识。
通过跨平台基准测试,我可以报告两个方面的改进。
.NET Core加速:JIT编译
在基准测试场景中,吞吐量周期的顺序基线是测量相同硬件上潜在加速的有用工具,并且给定代码在.Net Core 2.1上比在.Net 4.7.2上快1.997倍。这并不意味着每个代码都会快这几倍,只是某些代码可以更有效地JIT从而运行得更快,但潜在的加速总是依赖于代码,在某些情况下,进一步优化是不可能的。对于某些特定情况,Stephen Toub报告了类似的加速。
图表 1:顺序吞吐量加速 .NET / .NET Core(加速取决于代码)
.NET Core加速:C# lock——监控类改进
跨平台基准测试的结果表明,在重负载场景和坏邻居场景下,C# lock(Monitor 类)也有了相当大的改进。
.NET实现很容易出现CPU僵局,C# lock(Monitor 类)在这一时刻浪费了大部分CPU资源而几乎没有完成任何工作,有效的同步成本占用了大部分CPU资源。这在之前的文章中已有报道。
.NET Core 2.1似乎有更好的C# lock实现方式(.NET Core 2.1运行时的C++中的Monitor 类/AwareLock类)。
图 2:.Net 和 .Net Core 上的 C# lock(Monitor 类)和 .Net Core 上的 LockUC 的 CPU 资源浪费。
根据图表2,很容易得出.NET Core 2.1在性能方面的优势。C# lock通常散布在大多数项目的代码中,并且是许多公共库的一部分,包括运行时本身,在这里,我们看到在某些时序情况下CPU资源得到了显着改善,CPU浪费减少了80%以上!请比较 C# lock Monitor类的蓝色和绿色趋势线。
JIT改进很重要,但充满C# lock的多线程代码在从简单到业务线代码库的许多项目中仍然普遍存在。
即使是简单的项目,性能提升也可能是可观的,并且通过访问WinForms和WPF升级到.NetCore 3.0的动机可能非常有趣。
这是.NetCore 2.1的一个重要改进,但仍有改进的空间,例如,我们可以考虑LockUC,请比较绿色和红色趋势线,这表明仍有10%左右的收益,但它通常部分被低于1ms吞吐量周期的稍差的吞吐量所购买,其中基于原子指令的同步原语可以帮助获得吞吐量,同时管理合理的CPU浪费,但这需要现代架构设计与多核时代的处理器计数。
跨平台基准
图 3:C# lock(Monitor) / LockUC 在重负载场景下的跨基准测试,.NET 4.7.2,16 核。
图 4:C# lock(Monitor) / LockUC 在重负载场景下的跨基准测试,.Net Core 2.1,16 核。
概括
本文是该GreenSuperGreen库的.NET Standard 2.0版本(带有内置统一并发)的公告,其中包括对该库的一些改进。
我们已经讨论并通过跨平台基准测试展示了从.NET升级到.NET Core 2.1+的巨大潜力和动力,这要归功于JIT编译改进以及多线程代码的改进,这要归功于C# lock(Monitor 类)的改进减少CPU浪费。
https://www.codeproject.com/Articles/1271910/Unified-Concurrency-IV-going-cross-platform