<div dir="ltr"><div dir="ltr">Am Di., 10. Okt. 2023 um 15:56 Uhr schrieb Alan Bateman <<a href="mailto:Alan.Bateman@oracle.com">Alan.Bateman@oracle.com</a>>:<br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div>
    There's a table of system properties in the java.lang.Thread javadoc
    with the configuration, you probably want
    -Djdk.virtualThreadScheduler.maxPoolSize=<N> for your testing.
    It's hard to know what to take from your mail as virtual thread are
    only going to help if most of the time is spent blocking at the
    queue, the compilation and class generation tasks seem very compute
    bound.</div></blockquote><div><br></div><div>Reducing maxPoolSize did not move the needle much.</div><div><br></div><div>Another idea was more fruitful.  Virtual threads are competing for computing resources with other parts of the JVM: compilation, garbage collection, and probably more.  At around 16 logical cores compilation grabs itself an outsize portion of this pie, which shows up in -XX:+PrintFlagsFinal as</div><div><br></div><div>@@ -50,7 +50,7 @@<br>      bool C1ProfileInlinedCalls                    = true                                   {C2 product} {default}<br>      bool C1ProfileVirtualCalls                    = true                                   {C2 product} {default}<br>      bool C1UpdateMethodData                       = true                                   {C2 product} {default}<br>-     intx CICompilerCount                          = 4                                         {product} {ergonomic}<br>+     intx CICompilerCount                          = 12                                        {product} {ergonomic}<br>      bool CICompilerCountPerCPU                    = true                                      {product} {default}<br>      bool CITime                                   = false                                     {product} {default}<br>      bool CheckJNICalls                            = false                                     {product} {default}<br></div><div><br></div><div>Taking 8+0+0 (8 P-cores, no HT, no E-cores) as a starting point, running 200 back to back iterations results in these timings (with ~570k fine grained virtual threads):</div><div><br></div><div>real 71.37<br>user 394.47<br>sys 8.05<br></div><div><br></div><div>When adding hyperthreading and going to 8+8+0, user & sys time degrade significantly and real time somewhat:</div><div><br></div><div>real 83.06<br>user 776.37<br>sys 16.38<br></div><div><br></div><div>But 8+8+0 plus -XX:CICompilerCount=4 closes most of the distance to the 8+0+0 timings again:</div><div><br></div><div>real 74.23<br>user 477.18<br>sys 9.75<br></div><div><br></div><div>The picture is similar when looking only at the elapsed time of the very first bootstrap iteration in isolation, i.e. when warmup is just starting.</div><div><br></div><div>Adding more options to revert to the 8+0+0 garbage collection settings seems to be a wash, and setting maxPoolSize and parallelism to 8 seems to be slightly beneficial here.</div><div><br></div><div><br></div><div>Overlaid over this seems to be a degrading return on investment for hyperthreading when increasing core count.  Going from 4+0+0 to 4+4+0 is good for a real time speedup of 1.07, while going from 8+0+0 to 8+8+0 gives a speedup of 0.97, i.e. a slowdown.</div><div><br></div><div>-- mva</div><div><br></div></div></div>