Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8227006

[linux] Runtime.availableProcessors execution time increased by factor of 100

    XMLWordPrintable

Details

    • b02
    • b22
    • x86_64
    • linux

    Backports

      Description

        ADDITIONAL SYSTEM INFORMATION :
        This does seem to be somewhat hardware dependent - some VMs don't exhibit the problem, and we haven't seen this on Windows yet. We've seen this on Linux 64-bit Openstack VMs, in at least 3 different setups.

        A DESCRIPTION OF THE PROBLEM :
        We have observed a significant performance regression in the Runtime.availableProcessors native API call.

        On JDK versions prior to 1.8b191, a simple program can achieve upwards of 4 million calls to Runtime.availableProcessors a second on our test hardware.
        On JDK build 1.8b191 and all later major and minor versions, including 11, the maximum it can achieve is around 40,000 calls a second - a performance drop of 100x.

        This causes performance issues for CompletableFuture.waitingGet, which calls Runtime.availableProcessors in a tight loop as part of its spinwait - which is how we originally found the issue, as our application was exhibiting significant performance problems in our asynchronous code.

        REGRESSION : Last worked in version 8u192

        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
        Run the attached program on JDK version 1.8b182, and 1.8b191, on a 64bit Linux machine.

        EXPECTED VERSUS ACTUAL BEHAVIOR :
        EXPECTED -
        The performance should be the same
        ACTUAL -
        The performance drops by a factor of 100.

        ---------- BEGIN SOURCE ----------
            public static void main(String[] args) throws Exception {
                AtomicBoolean stop = new AtomicBoolean();
                AtomicInteger count = new AtomicInteger();

                new Thread(() -> {
                    while (!stop.get()) {
                        Runtime.getRuntime().availableProcessors();
                        count.incrementAndGet();
                    }
                }).start();

                try {
                    int lastCount = 0;
                    while (true) {
                        Thread.sleep(1000);
                        int thisCount = count.get();
                        System.out.printf("%s calls/sec%n", thisCount - lastCount);
                        lastCount = thisCount;
                    }
                }
                finally {
                    stop.set(true);
                }
            }
        ---------- END SOURCE ----------

        CUSTOMER SUBMITTED WORKAROUND :
        None possible.

        FREQUENCY : often


        Attachments

          Issue Links

            Activity

              People

                bobv Bob Vandette (Inactive)
                webbuggrp Webbug Group
                Votes:
                0 Vote for this issue
                Watchers:
                12 Start watching this issue

                Dates

                  Created:
                  Updated:
                  Resolved: