Оптимизация не встроенных методов JVM - PullRequest
0 голосов
/ 20 сентября 2018

Я в основном знаю о некоторых вещах, которые JVM может делать после , она включает метод, такой как scalar replacement, escape analysis или lock elision и т. Д. (Я признаю, что я не знаю всех их).Но что, если метод слишком велик, чтобы его можно было встроить?Есть ли какие-либо оптимизации, которые JVM может сделать с этими методами?Я думаю loop unrolling будет один ...

Кто-нибудь, кто знает, что субъект может пролить свет?

Ответы [ 2 ]

0 голосов
/ 23 сентября 2018

Встраивание - это разновидность убер-оптимизации, которая расширяет контекст для многих других оптимизаций: устранение общего подвыражения, постоянное распространение, скалярная замена и т. Д. Не встроенный метод является черным ящиком - JVM не знает, изменяет ли такой метод объектполя, выбросы исключений, регистры, которые он портит, и т. д.

Встраивание облегчает другие оптимизации, но это не означает, что другие оптимизации не могут работать без встраивания.Модуль компиляции JIT - это метод, и JVM может применить почти все оптимизации к большому не встроенному методу в своей области видимости.Представьте, что вы создали очень большой метод, вставив всех вызываемых вручную в исходный код.Таким образом, независимо от того, выполняется ли вставка вручную или автоматически, график потока результатов / потока данных будет примерно одинаковым, поэтому JIT сможет обрабатывать оба случая.

В частности, Escape-анализ будет отлично работать внутрибольшой метод;выделения и блокировки все еще можно устранить, если они не избегают этого метода.

Позвольте мне продемонстрировать это с помощью следующего теста JMH.Запустите его с -prof gc, чтобы убедиться, что никакие объекты не выделены как во встроенном, так и в не встроенном случаях.

@State(Scope.Benchmark)
public class Inline {
    double x = 111;
    double y = 222;

    @Benchmark
    public double inline() {
        return doInline(x, y);

    }

    @Benchmark
    public double noinline() {
        return dontInline(x, y);
    }

    @CompilerControl(CompilerControl.Mode.INLINE)
    private double doInline(double a, double b) {
        return new Vector2D(a, b).norm();
    }

    @CompilerControl(CompilerControl.Mode.DONT_INLINE)
    private double dontInline(double a, double b) {
        return new Vector2D(a, b).norm();
    }

    static class Vector2D {
        private final double x;
        private final double y;

        public Vector2D(double x, double y) {
            this.x = x;
            this.y = y;
        }

        public double norm() {
            return Math.sqrt(x * x + y * y);
        }
    }
}

Очевидное требование для скалярной замены в HotSpot - это конструктор объекта и все его вызываемые методывстраиваются, но сам вызывающий не нуждается в встраивании.

0 голосов
/ 20 сентября 2018

Исключение проверки диапазона будет примером оптимизации, которая не требует встраивания.Взгляните на раздел Performance Techniques вики OpenJDK, чтобы получить больше примеров, длинный список оптимизаций приведен в PerformanceTacticIndex .

...