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

Suboptimal register allocation for simple loops

XMLWordPrintable

    • Cause Known
    • generic
    • generic

      In the following program, the second loop executes 4-5 times slower than the first loop
      even though the code is identical.

      Looking at the generated code generated on SPARC, the actual body of the loops gets optimized away so the only difference is in the code generated for the loop
      interation count. In the second loop, both the iteration count and loop limit
      are spilled and reloaded each iteration of the loop. In the first loop, the iteration
      count is kept in a register but the limit is spilled. There are more than
      enough registers to hold both.

      public class Bug {

          public static final long ITERATIONS = 100000000L;

          static boolean equalsEmpty(String s) {
              return s.equals("");
          }

          static void warmUp() {
              String equalsOperand = "";
              String lengthOperand = "";
              boolean equalsResult = true;
              boolean lengthResult = true;

              System.out.println("Beginning warmup ...");
              for (long i = 0; i < 5000; i += 1) {
                doLoops(5000);
              }
              for (long i = 0; i < 5000; i += 1) {
                doLoops(5000);
              }
              for (long i = 0; i < 5000; i += 1) {
                doLoops(5000);
              }
              System.out.println("Warmed up");
          }

          static long loop1Time;
          static long loop2Time;
          static void doTiming(long iterations) {
           doLoops(iterations);
           System.out.println("loop1: " + Long.toString(loop1Time));
           System.out.println("loop2: " + Long.toString(loop2Time));
          }

          static void doLoops(long iterations) {
              String loop1Operand = "";
              String loop2Operand = "";
              boolean loop1Result = true;
              boolean loop2Result = true;
              long loop1Begin = 0L;
              long loop1End = 0L;
              long loop2Begin = 0L;
              long loop2End = 0L;

              loop1Begin = System.currentTimeMillis();
              for (long i = 0; i < iterations; i += 1) {
                  loop1Result |= equalsEmpty(loop1Operand);
              }
              loop1End = System.currentTimeMillis();
              loop1Time = loop1End - loop1Begin;

              loop2Begin = System.currentTimeMillis();
              for (long i = 0; i < iterations; i++) {
                  loop2Result |= equalsEmpty(loop2Operand);
              }
              loop2End = System.currentTimeMillis();
              loop2Time = loop2End - loop2Begin;
          }


          public static void main(String[] args) {
              System.out.println("Begin test, ITERATIONS = " + ITERATIONS);
              // Warm up
              warmUp();

              // Timing runs
              doTiming(ITERATIONS);
              doTiming(ITERATIONS);
              doTiming(ITERATIONS);
              doTiming(ITERATIONS);
              doTiming(ITERATIONS);
          }
      }

            Unassigned Unassigned
            sdeversunw Steve Dever (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Imported:
              Indexed: