JDK16关于TCP和UDP的优化

文章转自belaban.blogspot.com

Double your performance: virtual threads (fibers) and JDK 15/16!
If you use UDP as transport and want to double your performance: read on!

If you use TCP, your performance won't change much. You might still be interested in what more recent JDKs and virtual threads (used to be called 'fibers') will bring to the table.

Virtual threads

Virtual threads are lightweight threads, similar in concept to the old Green Threads, and are managed by the JVM rather than the kernel. Many virtual threads can map to the same OS native (carrier) thread (only one at a time, of course), so we can have millions of virtual threads.

Virtual threads are implemented with continuations, but that's a detail. What's important is that all blocking calls in the JDK (LockSupport.park() etc) have been modified to yield rather than block. This means that we don't waste the precious native carrier thread, but simply go to a non-RUNNING state. When the block is over, the thread is simply marked as RUNNABLE again and the scheduler continues the continuation where it left off.

Main advantages:
Blocking calls don't need to be changed, e.g. into reactive calls
No need for thread pools: simply create a virtual thread
Fewer context switches (reduced/eliminated blocking calls)
We can have lots of virtual threads
It will be a while until virtual threads show up in your JDK, but JGroups has already added support for it: just set use_fibers="true" in the transport. If the JVM supports virtual threads, they will be used, otherwise we fall back to regular native threads.


UDP: networking improvements
While virtual threads bring advantages to JGroups, the other performance increase can be had by trying a more recent JDK.

Starting in JDK 15, the implementation of DatagramSockets and MulticastSockets has been changed to delegate to DatagramChannels and MulticastChannels. In addition, virtual threads are supported.

This increases the performance of UDP which uses DatagramChannels and MulticastChannels.

The combination of networking code improvements and virtual threads leads to astonishing results for UDP, read below.

Performance
I used UPerf for testing on a cluster of 8 (physical) boxes (1 GBit ethernet), with JDKs 11, 16-ea5 and 16-loom+2-14. The former two use native threads, the latter uses virtual threads.

As can be seen in [1], UDP's performance goes from 44'691 on JDK 11 to 81'402 on JDK 16-ea5; that's a whopping 82% increase! Enabling virtual threads increases the performance between 16-ea5 and 16-loom+2-14 to 88'252, that's another 8%!

The performance difference between JDK 11 and 16-loom is 97%!

The difference in TCP's performance is miniscule; I guess because the TCP code was already optimized in JDK 11.

Running in JDK 16-loom+2-14 shows that UDP's performance is now on par with TCP, as a matter of fact, UDP is even 3% faster than TCP!

If you want to try for yourself: head over to the JGroups Github repo and create the JAR (ant jar). Or wait a bit: I will soon release 5.0.0.Final which contains the changes.

Not sure if I want to backport the changes to the 4.x branch...

Enjoy!

[1] https://drive.google.com/file/d/1Ars1LOM7cEf6AWpPwZHeIfu_kKLa9gv0/view?usp=sharing

[2] http://openjdk.java.net/jeps/373

性能加倍:虚拟线程(光纤)和JDK15/16!
如果您使用UDP作为传输,并希望将性能提高一倍:请继续阅读!
如果使用TCP,性能不会有太大变化。您可能仍然对最近的jdk和虚拟线程(以前称为“fibers”)将带来什么感兴趣。
虚拟线程
虚拟线程是轻量级线程,在概念上类似于旧的绿色线程,由JVM而不是内核来管理。许多虚拟线程可以映射到同一个操作系统本机(运营商)线程(当然,一次只能映射一个),因此我们可以拥有数百万个虚拟线程。
虚拟线程是用continuations实现的,但这只是一个细节。重要的是JDK中的所有阻塞调用(停车场锁支架()等)已修改为屈服而不是阻塞。这意味着我们不会浪费宝贵的本机载波线程,而只是进入非运行状态。当块结束时,线程被简单地再次标记为可运行,调度程序在它停止的地方继续继续执行。
主要优点:
阻塞呼叫不需要更改,例如变为被动呼叫
不需要线程池:只需创建一个虚拟线程
更少的上下文切换(减少/消除阻塞调用)
我们可以有很多虚拟线程
虚拟线程在JDK中出现还需要一段时间,但JGroups已经添加了对它的支持:只需在传输中设置use_fibers=“true”。如果JVM支持虚拟线程,那么将使用它们,否则我们将返回到常规的本机线程。
UDP:网络改进
虽然虚拟线程为jgroup带来了优势,但通过尝试更新的JDK,可以获得其他性能提升。
从jdk15开始,DatagramSockets和MulticastSockets的实现已经改为委托给DatagramChannels和multicast channels。此外,还支持虚拟线程。
这提高了UDP使用DatagramChannels和multicast channels的性能。
网络代码改进和虚拟线程的结合为UDP带来了惊人的结果,如下所示。
性能
用于以太网测试(1-16个)和1-5个虚拟机的JDEAK(16个)和1个。前两个使用本机线程,后一个使用虚拟线程。
从[1]中可以看出,UDP的性能从jdk11上的44'691提高到jdk16-ea5上的81'402;这是惊人的82%的增长!启用虚拟线程可以将16-ea5和16织机+2-14之间的性能提高到88'252,这又是8%!
jdk11和16织机的性能差异是97%!
TCP的性能差别很小;我想是因为TCP代码已经在jdk11中进行了优化。
在jdk16loom+2-14上运行表明UDP的性能已经与TCP不相上下,事实上UDP甚至比TCP快3%!
如果您想自己尝试一下:转到JGroups Github repo并创建JAR(antjar)。或者稍等一下:我很快就会发布5.0.0.Final,其中包含了这些更改。
不确定是否要将更改后传到4.x分支。。。
享受吧!
[1]https://drive.google.com/file/d/1Ars1LOM7cEf6AWpPwZHeIfu kKLa9gv0/view?usp=分享
[2]http://openjdk.java.net/jeps/373

新鲜刺激的东西永远都有,玩之前掂量掂量自己几斤几两
原文地址:https://www.cnblogs.com/banxianer/p/13360223.html