2016-11-10 2 views
1

Когда я прочитал об оптимизации, я рассказал о разворачивании цикла. Сделав небольшой поиск в Google, я не нашел, если это делает компилятор Java.Производительность Java - цикл разворачивания

Таким образом, лучший способ - попробовать, если я сам.

На самом деле я был совершенно удивлен фактом, что на самом деле, выполняя этот цикл разворачивания, мне удалось ускорить его, так как я был совершенно уверен, что современные компиляторы делают это для меня.

public static void folded() { 
    System.out.println("Folded:"); 
    long c1 = System.currentTimeMillis(); 

    for (int r = 0; r < 10; r++) { 
     for (int i = 0; i < 500000; i++) { 
      Math.sin(i); 
     } 
    } 
    System.out.println(System.currentTimeMillis() - c1); 
} 

public static void unFolded() { 
    System.out.println("Unfolded:"); 
    long c1 = System.currentTimeMillis(); 

    for (int r = 0; r < 10; r++) { 
     for (int i = 0; i < 500000; i += 10) { 
      Math.sin(i); 
      Math.sin(i + 1); 
      Math.sin(i + 2); 
      Math.sin(i + 3); 
      Math.sin(i + 4); 
      Math.sin(i + 5); 
      Math.sin(i + 6); 
      Math.sin(i + 7); 
      Math.sin(i + 8); 
      Math.sin(i + 9); 
     } 
    } 
    System.out.println(System.currentTimeMillis() - c1); 
} 

РЕЗУЛЬТАТ (СЧЕТЧИК 500'000):

Сложенный: 453

разложенном: 114

РЕЗУЛЬТАТ (СЧЕТЧИК 5'000'000):

Сложенный: 13850

Undefined: 11929

И чем я должен доверять? Ручная оптимизация или компиляторы? Поскольку в этом тесте мой результат показывает, что оптимизация вручную кажется лучше.

+2

Я голосующий, чтобы закрыть этот вопрос как не относящийся к теме, потому что это вопрос оптимизации кода, который может быть лучше связан с http://codereview.stackexchange.com/ – Freiheit

+0

Если вы действительно хотите сделать такие тесты, у вас есть для изучения инструкций через 'javap' –

+2

Рассмотрите возможность чтения http://stackoverflow.com/questions/504103/how-do-i-write-a-correct-micro-benchmark-in-java. – bradimus

ответ

0

Цепь для незакрепленных папок может быть полезна, когда вы можете распараллеливать развернутые операции. Для этого многие современные процессоры поддерживают векторные инструкции https://en.wikipedia.org/wiki/Vector_processor

Начиная с 7u40 серверный компилятор для Java поддерживает основные векторные инструкции http://bugs.java.com/view_bug.do?bug_id=6340864. Как arrayA[0..n] + arrayB[0..n] и т. Д. Узнайте больше о Do any JVM's JIT compilers generate code that uses vectorized floating point instructions?

В вашем случае развернутая операция - Math.sin(...), что является более чем одной инструкцией CPU. В результате Java не может преобразовать его в любую известную команду вектора ЦП и обеспечить преимущество производительности по сравнению с циклом.

+2

Этот ответ противоречив друг другу. В нем объясняется, что компилятор JIT может развернуть цикл, чтобы повысить производительность, что прямо поражает утверждение OP о том, что разворот цикла на уровне Java может иметь какой-либо эффект. Тем не менее, это не указывает на это, вместо этого указывая, что «грех» не может быть векторизован. Подразумевается, что он утверждает ложь: «Если бы« грех »мог быть векторизован, то требование ОП было бы правильным». –

Смежные вопросы