SlideShare a Scribd company logo
1 of 80
Download to read offline
Java Benchmarking
как два таймстампа прочитать!
Алексей Шипилёв
aleksey.shipilev@oracle.com, @shipilev
The following is intended to outline our general product direction. It
is intended for information purposes only, and may not be
incorporated into any contract. It is not a commitment to deliver any
material, code, or functionality, and should not be relied upon in
making purchasing decisions. The development, release, and timing
of any features or functionality described for Oracle’s products
remains at the sole discretion of Oracle.
Slide 2/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Введение
Slide 3/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Введение: В качестве разогрева
«Сколько стоит создание одного String?»
long startTime = System.nanoTime ();
for (int i = 0; i < 1000; i++) {
String s = new String("");
}
long stopTime = System.nanoTime ();
System.out.println("Time:" + (stopTime - startTime ));
Slide 4/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Теория
Slide 5/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Теория: Зачем люди делают бенчмарки?
1. Ради холивора: мой язык лучше твоего языка
2. Ради маркетинга: проверить, что мы вкладываемся в
конкретные критерии
3. Ради инжиниринга: изолировать и зафиксировать
перформансный феномен, чтобы была референсная точка
для улучшения
4. Ради науки: понять, какой моделью описывается система,
и на основании этой модели предсказать будущее поведение
Slide 6/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Теория: Ради холивора
Прекрасный пример – Computer Language Benchmarks Game:1
Многие реализации вообще не сравнимы: e.g. AOT vs. JIT
Измеряют непонятно что: e.g. pidigits измеряет скорость
интерфейса до GMP
Куча дисклеймеров про то, что в реальной жизни всё может
быть по-другому: и тогда этот проект нужен только ради
лулзов
Любят его потому, что CLBG даёт числа, которыми можно
размахивать в холиворах
1
http://benchmarksgame.alioth.debian.org/
Slide 7/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Теория: Ради маркетинга
Прекрасный пример – SPEC benchmarks:
Референсные наборы бенчмарок, одинаково хороших/плохих
для большинства вендоров
Позволяют иметь референсные точки, против которых
можно выставлять критерии успешности продукта, писать в
рекламе и т.п.
Ну и что, что они не всегда репрезентативны – главное, что
они «золотые»
Slide 8/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Теория: Ради инжиниринга
«If you can’t measure it, you can’t optimize it»
Нужны лабораторные условия, в которых зафиксировано
конкретное состояние системы, чтобы можно было
проверять внесённые изменения
Обычно фокусируются на конкретных местах продукта,
имеют бОльшую разрешающую способность, чем
маркетинговые бенчи
Размеры и охват этих бенчмарков зависит от укуренности
инженеров
Slide 9/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Теория: Ради науки
«Science Town PD: To Explain and Predict»
Извлечь из результатов тестов правдоподобную модель
производительности
Из модели получить предсказания о будущем поведении,
проверить эти предсказания, спокойно вздохнуть и
деплойнуть в прод
Самая трудоёмкая, и самая надёжная цель бенчмаркинга
Slide 10/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Теория: Что интересно нам?
1. Ради холивора: мой язык лучше твоего языка
2. Ради маркетинга: проверить, что мы вкладываемся в
конкретные критерии
3. Ради инжиниринга: изолировать и зафиксировать
перформансный феномен, чтобы была референсная точка
для улучшения
4. Ради науки: понять, какой моделью описывается система,
и на основании этой модели предсказать будущее поведение
Slide 11/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Теория: Бенчмарки – это эксперименты
Хорошие эксперименты отвечают на несколько групп вопросов:
1. Что измеряем: какие метрики используем? Что эти
метрики нам говорят?
2. Как измеряем: какими способами мы измеряем метрики?
какая точность у этих способов? какие подводные камни?
3. Как проверяем: как поверяем наши инструменты? как
узнаём, что результатам можно доверять?
Slide 12/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Что измеряем: Метрики
Две главные группы метрик:
Bandwidth (𝜆)
Сравнительно легко
измерить
Легко вводится в steady
state
Скрывает большие
задержки
Упускает active-idle
Latency (𝜏)
Трудно измерить корректно
Средняя latency как
правило бессмыслена
Нужно считать квантили
Семплы меньше 1мкс
получить не практично
Slide 13/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Что измеряем: путаем bandwidth и latency
Отличия в нагрузке:
– 𝜆 обычно измеряют под пиковой нагрузкой
– 𝜏 как правило измеряют под регулируемой нагрузкой
– Нагрузка – это новая степень свободы!
Отличия в подходах к измерению:
– Средняя задержка – бессмысленная метрика, ибо
𝜏 𝑎𝑣𝑔 = 1
𝜆
– Нужно мерить каждое событие, и считать квантили!
– События короче 1 мкс? Мухаха.
Slide 14/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Что измеряем: 𝜆 и 𝜏 – братья навек
Slide 15/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Как измеряем: типы бенчмарок
Два главных подхода:
Time-based
Исполняем постоянное
время
Делаем операции одну за
одной
В измерение умещаем
порядочное количество
операций
Fixed work
Исполняем постоянное
количество операций
Чаще всего одну операцию
Здорово экономит время!
Slide 16/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Как измеряем: Transients
Запомните
Мы имеем дело с динамическими системами.
«Прогрев» – это выжидание характерного времени
переходного процесса.
У нас полно переходных процессов.
Slide 17/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Как измеряем: Transients
Запомните
Мы имеем дело с динамическими системами.
«Прогрев» – это выжидание характерного времени
переходного процесса.
У нас полно переходных процессов.
Компиляция кода – не единственный переходный процесс!
Slide 17/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Как измеряем: Transients
Запомните
Мы имеем дело с динамическими системами.
«Прогрев» – это выжидание характерного времени
переходного процесса.
У нас полно переходных процессов.
Компиляция кода – не единственный переходный процесс!
«Мудрость»: «Cледите за PrintCompilation». WTF?
Slide 17/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Как измеряем: Steady state
Система пришла в устойчивое состояние (steady state), когда
все её переходные процессы устканились
Любое изменение выбивает её из steady state
Slide 18/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Как измеряем: Иногда steady state нет!
public class FibonacciGen {
BigInteger n1 = ONE; BigInteger n2 = ZERO;
public BigInteger next () {
BigInteger cur = n1.add(n2);
n2 = n1; n1 = cur;
return cur;
}
}
Каждый вызов next() всё медленней и медленней
Имеет смысл измерять первые N операций – а там transients!
Slide 19/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Как проверяем: Инженерный подход
Главный инженерный вопрос
Почему мой бенчмарк не может работать быстрее?
Ответ определяет качество эксперимента:
1. В какие ограничения упёрлись?
2. Работает та часть кода, которую мы «исследуем»?
3. Что сделать, чтобы исправить бенчмарк?
Slide 20/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Как проверяем: Научный подход
Главный научный вопрос
Как бенчмарк реагирует на изменение внешних условий?
Отвечаем, насколько актуальная модель разнится с ментальной:
1. Проверка на дурака: имеют ли смысл эти результаты?
2. Негативный контроль: меняется ли результат от
варирования переменной 𝑋𝑖, хотя не должен?
3. Позитивный контроль: не меняется ли результат от
варирования переменной 𝑌𝑖, хотя должен?
Slide 21/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Практика
Slide 22/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Практика: JMH
У нас тоже есть очень хороший харнесс:
http://openjdk.java.net/projects/code-tools/jmh/
JMH is Serious Business:
– Он учитывает тонну VM-ных эффектов
– Мы его периодически допиливаем, когда меняется VM
– Мы его периодически фиксим, как растёт наша экспертиза
– Всякий внешний бенч валидируется переписыванием под JMH
Slide 23/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Практика: JMH
У нас тоже есть очень хороший харнесс:
http://openjdk.java.net/projects/code-tools/jmh/
JMH is Serious Business:
– Он учитывает тонну VM-ных эффектов
– Мы его периодически допиливаем, когда меняется VM
– Мы его периодически фиксим, как растёт наша экспертиза
– Всякий внешний бенч валидируется переписыванием под JMH
Мы вынули столько неочевидных граблей из JMH,
что не верим ни одному известному харнессу.
Slide 23/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Практика: Цель
Цель всего этого мероприятия в том,
чтобы вас как следует напугать
и заставить бросить:
(тупо) писать обёртки для бенчмарок
(тупо) доверять обёрткам для бенчмаркок
(тупо) доверять бенчмаркам
Slide 24/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
System: Задачка (A)
Давайте запустим простенький бенчмарк.
Система говорит, что у неё 4 CPU.
Threads Ops/nsec Scale
1 3.06 ± 0.10
2 5.72 ± 0.10 1.87 ± 0.03
4 5.87 ± 0.02 1.91 ± 0.03
Slide 25/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
System: Задачка (A)
Давайте запустим простенький бенчмарк.
Система говорит, что у неё 4 CPU.
Threads Ops/nsec Scale
1 3.06 ± 0.10
2 5.72 ± 0.10 1.87 ± 0.03
4 5.87 ± 0.02 1.91 ± 0.03
Вопрос 1: Почему переход 2 → 4 потока такой хилый?
Slide 25/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
System: Задачка (A)
Давайте запустим простенький бенчмарк.
Система говорит, что у неё 4 CPU.
Threads Ops/nsec Scale
1 3.06 ± 0.10
2 5.72 ± 0.10 1.87 ± 0.03
4 5.87 ± 0.02 1.91 ± 0.03
Вопрос 1: Почему переход 2 → 4 потока такой хилый?
Вопрос 2: Почему переход 1 → 2 потока всего 1.87x?
Slide 25/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
System: Power management
Запускаем простой бенчмарк,
+ и зажимаем частоту CPU в 2 GHz:
Threads Ops/nsec Scale
1 1.97 ± 0.02
2 3.94 ± 0.05 2.00 ± 0.02
4 4.03 ± 0.04 2.04 ± 0.02
Slide 26/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
System: Power management
Многие подсистемы балансируют power-vs-performance
(Ex.: cpufreq, SpeedStep, Cool&Quiet, TurboBoost)
Засада: ломает гомогенность времени
Костыль: выключить PM, зажать частоту CPU
JMH: работаем дольше, не паркуем потоки
Slide 27/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
System: OS Schedulers
Шедулеры OS балансируют affinity-vs-power
(Ex.: Solaris schedulers, Linux power-efficient taskqueues)
Засада: ломает иллюзию симметричности CPU
Костыль: зажать политики шедулинга
JMH: работаем дольше, не паркуем потоки
Slide 28/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
System: Time Sharing
Системы разделяемого времени балансируют
утилизацию.
(Ex.: тысячи их)
Засада: старт/останов потоков не мгновенный, время
работы потоков не детерминировано, загрузка во времени
неоднородна
Костыль: удостовериться, что все потоки начали
исполнять работу
JMH: «synchronize iterations»
Slide 29/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
System: Time Sharing, #2
JMH – synchronize iterations:
Slide 30/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
System: Time Sharing, Quiz (B)
public void measure () {
long startTime = System.nanoTime ();
while (! isDone) {
work ();
}
println(System.nanoTime () - startTime );
}
Slide 31/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
System: Time Sharing, Задачка (B)
«Is there a problem, officer?»
public void measure () {
long realTime = 0;
while (! isDone) {
setup (); // skip this
long time = System.nanoTime ();
work ();
realTime += (System.nanoTime () - time );
}
println(realTime );
}
Slide 32/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
System: Time Sharing, Задачка (B)
Измеряем количество вызовов в секунду, да?
0
200
400
600
0 10 20 30
# Threads
throughput,ops/us
Timing the entire loop Timing the sum[iterations]
...а оно растёт за количество CPU – WTF?!
Slide 33/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
System: Time Sharing, Задачка (B)
public void measure () {
long startTime = System.nanoTime ();
long realTime = 0;
while (! isDone) {
setup (); // skip this
long time = System.nanoTime ();
work ();
realTime += (System.nanoTime () - time );
...WHOOPS, WE DE-SCHEDULE HERE...
}
println(realTime );
println(System.nanoTime () - startTime );
}
Slide 34/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
System: Time Sharing
Разделение времени даёт иллюзию параллельной
работы нескольких потоков
Засада: эта иллюзия не всегда выполняется для
производительности!
Костыль: никогда не перегружать систему!
JMH: большой красный флаг на въезде в страну
Slide 35/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
VM: Задачка (C)
@GenerateMicroBenchmark
public void baseline () {
}
0.5 ± 0.1 ns
@GenerateMicroBenchmark
public void measureWrong () {
Math.log(x);
}
0.5 ± 0.1 ns
@GenerateMicroBenchmark
public double measureRight () {
return Math.log(x);
}
34.0 ± 1.0 ns
Slide 36/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
VM: Dead-code elimination
Оптимизаторы очень хорошо удаляют код без
наблюдаемых эффектов.
Засада: может снести часть бенчмарка вдрабадан
Костыль: наводим эффекты на результаты (суммируем,
складываем, печатаем, и т.п.)
JMH: поддержка в API
Slide 37/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
VM: Задачка (D)
@GenerateMicroBenchmark
public void baseline () {
}
0.5 ± 0.1 ns
@GenerateMicroBenchmark
public double measureWrong () {
return Math.log (42);
}
1.0 ± 0.1 ns
private double x = 42;
@GenerateMicroBenchmark
public double measureRight () {
return Math.log(x);
}
34.0 ± 1.0 ns
Slide 38/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
VM: Constant folding, etc.
Оптимизаторы довольно хороши в предвычислениях.
Засада: может предоптимизировать часть бенчмарка
Костыль: сделать входные данные непредсказуемыми
JMH: поддержка в API
Slide 39/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
VM: CSE
JMH ломает спекуляцию о чтениях в разных вызовах @GMB
метода
double x;
@GenerateMicroBenchmark
double doWork () {
doStuff(x);
}
volatile boolean done;
void doMeasure () {
while (! done) {
doWork ();
}
}
(Перевод: читаем всё из кучи ⇒ мы спасены!)
Slide 40/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
VM: DCE, CSE... одно и то же!
Потеря непредсказуемости что источника, что результата теряет
и часть бенчмарка. Тихо и незаметно.
Slide 41/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
VM: DCE, CSE... одно и то же!
Потеря непредсказуемости что источника, что результата теряет
и часть бенчмарка. Тихо и незаметно.
Slide 41/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
VM: DCE, CSE... одно и то же!
Потеря непредсказуемости что источника, что результата теряет
и часть бенчмарка. Тихо и незаметно.
Slide 41/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
VM: Задачка (E)
// changing N, will performance differ?
static int N = 100;
@GenerateMicroBenchmark
public int test () { return doWork(N); }
int x = 1, y = 2;
private int doWork(int reps) {
int s = 0;
for (int i = 0; i < reps; i++)
s += (x + y);
return s;
}
Slide 42/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
VM: Задачка (E), #2
N ns/call ns/add
1 1.5 ± 0.1 1.5 ± 0.1
10 2.0 ± 0.1 0.1 ± 0.01
100 2.7 ± 0.2 0.05 ± 0.02
1000 68.8 ± 0.9 0.07 ± 0.01
10000 410.3 ± 2.1 0.04 ± 0.01
100000 3836.1 ± 40.6 0.04 ± 0.01
Slide 43/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
VM: Задачка (E), #2
N ns/call ns/add
1 1.5 ± 0.1 1.5 ± 0.1
10 2.0 ± 0.1 0.1 ± 0.01
100 2.7 ± 0.2 0.05 ± 0.02
1000 68.8 ± 0.9 0.07 ± 0.01
10000 410.3 ± 2.1 0.04 ± 0.01
100000 3836.1 ± 40.6 0.04 ± 0.01
Ну и какой строчке верить?
0.04 ns/add ⇒ 25 adds/ns ⇒ GTFO!
Slide 43/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
VM: Loop unrolling
Раскрутка циклов сильно расширяет диапазон
оптимизаций.
Засада: положим, одна итерация цикла занимает 𝑀 нс.
Тогда после раскрутки цикла она эффективно занимает 𝛼𝑀
ns, где 𝛼 ∈ [0; +∞)
Костыль: избегаем раскручиваемых циклов,
минимизируем эффекты от раскрутки
JMH: оказывается, что костыли для CSE/DCE так же
ломают эффекты от раскрутки
Slide 44/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
VM: Задачка (F)
interface M {
void inc ();
}
abstract class AM implements M {
int c;
void inc() {
c++;
}
}
class M1 extends AM {}
class M2 extends AM {}
Slide 45/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
VM: Задачка (F), #2
M m1 = new M1();
M m2 = new M2();
@GenerateMicroBenchmark
public void testM1 () { test(m1); }
@GenerateMicroBenchmark
public void testM2 () { test(m2); }
void test(M m) {
for (int i = 0; i < 100; i++)
m.inc ();
}
Slide 46/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
VM: Задачка (F), #3
test ns/op
testM1 4.6 ± 0.1
testM2 36.0 ± 0.4
Slide 47/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
VM: Задачка (F), #3
test ns/op
testM1 4.6 ± 0.1
testM2 36.0 ± 0.4
repeat testM1 35.8 ± 0.4
Slide 47/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
VM: Задачка (F), #3
test ns/op
testM1 4.6 ± 0.1
testM2 36.0 ± 0.4
repeat testM1 35.8 ± 0.4
forked testM1 4.5 ± 0.1
forked testM2 4.5 ± 0.1
Slide 47/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
VM: Profile feedback
Динамические оптимизации
могут использовать информацию времени исполнения
(Ex.: call profile, type profile, CHA info)
Засада: Серьёзная разница между режимами «всё в одной
VM» и «всё в отдельных VM»
Костыль: Прогреваем все бенчмарки вместе, ИЛИ
запускаем каждый бенчмарк в отдельной JVM
JMH: поддержка bulk warmup; forking
Slide 48/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
VM: Задачка (G)
Slide 49/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
VM: Задачка (G), #2
Slide 50/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
VM: Run-to-run variance
Многие масштабируемые алгоритмы не
детерминированы!
(Ex.: memory allocators, profiler counters, non-fair locks, concurrent
data structures, ...)
Засада: (потенциально) (огромная) разница между
запусками в одной конфигурации
Костыль: протоколирование решений на каждом уровне
(e.g. запись решений компилятора), несколько запусков JVM
JMH: несколько запусков JVM
Slide 51/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
VM: Inlining budgets
Подстановка (inlining) – это убер-оптимизация
Засада: Всё заинлайнить нельзя ⇒ приходится думать о
том, что инлайнится, а что нет
Костыль: Методы мельче, циклы мельче, подглядываем в
-XX:+PrintInlining, используем компиляторные хинты
JMH: генерируем горячие циклы в мелкие методы, даём
удобный @CompileControl
Slide 52/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
VM: сгенерированный JMH код
JIT-компиляция и подстановки начинаются с этого метода:
public void testLong_loop
(Loop loop , Result r, MyBenchmark bench) {
long ops = 0;
r.start = System.nanoTime ();
do {
bench.testLong (); // @GenerateMicroBenchmark
ops ++;
} while (! loop.isDone );
r.end = System.nanoTime ();
r.ops = ops;
}
Slide 53/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
CPU: Задачка (H)
@State
public class TreeMapBench {
Map <String , String > map = new TreeMap <>();
@Setup
public void setup () { populate(map); }
@GenerateMicroBenchmark
public void test(BlackHole bh) {
for(String key : map.keySet ()) {
String value = map.get(key);
bh.consume(value );
}
}
}Slide 54/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
CPU: Задачка (H), #2
@GenerateMicroBenchmark
public void test(BlackHole bh) {
for(String key : map.keySet ()) {
String value = map.get(key);
bh.consume(value );
}
}
Exclusive Shared
Throughput, op/sec 615 ± 12 828 ± 21
Slide 55/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
CPU: Задачка (H), #2
@GenerateMicroBenchmark
public void test(BlackHole bh) {
for(String key : map.keySet ()) {
String value = map.get(key);
bh.consume(value );
}
}
Exclusive Shared
Throughput, op/sec 615 ± 12 828 ± 21
Threads 4 4
Slide 55/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
CPU: Задачка (H), #2
@GenerateMicroBenchmark
public void test(BlackHole bh) {
for(String key : map.keySet ()) {
String value = map.get(key);
bh.consume(value );
}
}
Exclusive Shared
Throughput, op/sec 615 ± 12 828 ± 21
Threads 4 4
Maps 4 1
Slide 55/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
CPU: Задачка (H), #2
@GenerateMicroBenchmark
public void test(BlackHole bh) {
for(String key : map.keySet ()) {
String value = map.get(key);
bh.consume(value );
}
}
Exclusive Shared
Throughput, op/sec 615 ± 12 828 ± 21
Threads 4 4
Maps 4 1
Footprint, Kb 1024 256
Slide 55/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
CPU: Cache capacity
Основная память слишком далека.
Давайте кешировать всё прямо в проце!
Засада: Производительность заметно отличается в
зависимости от футпринта, путей обхода памяти, да и
банальной удачи
Костыль: Следим за футпринтом; пробуем разные
размеры данных; пробуем разные shared/unshared случаи
JMH: @State sharing
Slide 56/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
CPU: Задачка (I)
Насколько хорошо скалируется этот код?
@State(Scope.Benchmark) class Shared {
final int[] c = new int [64];
}
@State(Scope.Thread) class Local {
static final AtomicInteger COUNTER = ...;
final int index = COUNTER.incrementAndGet ();
}
@GenerateMicroBenchmark
void work(Shared s, Local l) {
s.c[l.index ]++;
}Slide 57/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
CPU: Задачка (I), #2
Threads Average ns/call Hit
1 2.0 ± 0.1
2 18.5 ± 2.4 9x
4 32.9 ± 6.2 16x
8 85.4 ± 13.4 42x
16 208.9 ± 52.1 104x
32 464.2 ± 46.1 232x
Почему?
Slide 58/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
CPU: Bulk method transfers
Система следит за когерентностью памяти по
кусочкам. Характерный размер кусочка: 32, 64, 128
байта.
Засада: модификация рядом лежащих данных разными
потоками даётся с трудом (false sharing)
Костыль: паддинг, subclass juggling, @Contended
JMH: все внутренние структуры отпажжены,
@State-объекты паддятся автоматически
Slide 59/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
CPU: Задачка (J)2
Exhibit B. Exhibit P.
int sum = 0;
for (int x : a) {
if (x < 0) {
sum -= x;
} else {
sum += x;
}
}
return sum;
int sum = 0;
for (int x : a) {
sum += Math.abs(x);
}
return sum;
Которая версия быстрее?
2
Credits: Sergey Kuksenko (@kuksenk0)
Slide 60/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
CPU: Задачка (J)
E. Branched E. Predicated
L0: mov 0xc(%ecx ,%ebp ,4) ,% ebx
test %ebx,%ebx
jl L1
add %ebx ,% eax
jmp L2
L1: sub %ebx ,% eax
L2: inc %ebp
cmp %edx ,% ebp
jl L0
L0: mov 0xc(%ecx ,%ebp ,4) ,% ebx
mov %ebx ,%esi
neg %esi
test %ebx ,% ebx
cmovl %esi,%ebx
add %ebx ,%eax
inc %ebp
cmp %edx ,%ebp
jl Loop
Которая версия быстрее?
Slide 61/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
CPU: Задачка (J)
Regular Pattern = (+, –)*
NHM Bldzr C-A9 SNB
branch_regular 0.9 0.8 5.0 0.5
branch_shuffled 6.2 2.8 9.4 1.0
branch_sorted 0.9 1.0 5.0 0.6
predicated_regular 2.0 1.0 5.3 0.8
predicated_shuffled 2.0 1.0 9.3 0.8
predicated_sorted 2.0 1.0 5.7 0.8
time, nsec/op
Slide 62/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
CPU: Branch Prediction
Out-of-Order процессоры очень много спекулируют.
Большую часть времени (99%+) делают это
корректно!
Засада: Провал в производительности, когда спекуляция
проваливается
Костыль: Реалистичные данные! Много, много разных
наборов данных
Slide 63/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Выводы
Slide 64/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Выводы: Benchmarking is Serious Business
Огромное поле для ошибок.
Написание тестов требует экспертизы
Написание фреймворков требует ещё большей экспертизы
Не верьте красивым репортам, верьте логичным результатам
Slide 65/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Выводы: инструменты
1. Мозг
– Плагин «данунеможетбыть» для перепроверок фактов
– Плагин «щапридумаем» для построения гипотез и экспериментов
– Плагин «чётоянепонял» для проверки консистентности гипотез
– Плагин «ядурак» для лёгкого отвержения ложных гипотез
2. Руки
– Прямые, для постановки аккуратных экспериментов
– Сильные, для обработки тонн экспериментальных данных
3. Язык, уши, глаза и прочее I/O
– Для обмена результатами и peer review
– Для доступа к предыдущим экспериментам
Slide 66/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
Выводы: прочие инструменты
1. Фреймворки
– JMH: http://openjdk.java.net/projects/code-tools/jmh/
2. Профилировщики
– VisualVM, JRockit Mission Control, Oracle Studio Performance
Analyzer
– top, vmstat, mpstat, iostat, dtrace, strace
3. Дизассемблеры
– -XX:+PrintAssembly
– https:
//wikis.sun.com/display/HotSpotInternals/PrintAssembly
Slide 67/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.

More Related Content

What's hot

Практика внедрения Scrum (статья)
Практика внедрения Scrum (статья)Практика внедрения Scrum (статья)
Практика внедрения Scrum (статья)Andrey Bibichev
 
System Engineering Webinar
System Engineering WebinarSystem Engineering Webinar
System Engineering WebinarPavel Veinik
 
Lean Software Development
Lean Software DevelopmentLean Software Development
Lean Software DevelopmentDmytro Mindra
 
Управление проектами по разработке в стиле Agile или Waterfall, чья доска круче?
Управление проектами по разработке в стиле Agile или Waterfall, чья доска круче?Управление проектами по разработке в стиле Agile или Waterfall, чья доска круче?
Управление проектами по разработке в стиле Agile или Waterfall, чья доска круче?SQALab
 
Graal, Truffle, SubstrateVM and other perks: what are those and why do you ne...
Graal, Truffle, SubstrateVM and other perks: what are those and why do you ne...Graal, Truffle, SubstrateVM and other perks: what are those and why do you ne...
Graal, Truffle, SubstrateVM and other perks: what are those and why do you ne...Oleg Chirukhin
 
Как заводить баги понятно всем
Как заводить баги понятно всемКак заводить баги понятно всем
Как заводить баги понятно всемSQALab
 
мартюшев почему юнит-тесты не работают. история большого проекта
мартюшев   почему юнит-тесты не работают. история большого проектамартюшев   почему юнит-тесты не работают. история большого проекта
мартюшев почему юнит-тесты не работают. история большого проектаMagneta AI
 
Behavior Driven Development
Behavior Driven DevelopmentBehavior Driven Development
Behavior Driven DevelopmentAlexey Tigarev
 

What's hot (8)

Практика внедрения Scrum (статья)
Практика внедрения Scrum (статья)Практика внедрения Scrum (статья)
Практика внедрения Scrum (статья)
 
System Engineering Webinar
System Engineering WebinarSystem Engineering Webinar
System Engineering Webinar
 
Lean Software Development
Lean Software DevelopmentLean Software Development
Lean Software Development
 
Управление проектами по разработке в стиле Agile или Waterfall, чья доска круче?
Управление проектами по разработке в стиле Agile или Waterfall, чья доска круче?Управление проектами по разработке в стиле Agile или Waterfall, чья доска круче?
Управление проектами по разработке в стиле Agile или Waterfall, чья доска круче?
 
Graal, Truffle, SubstrateVM and other perks: what are those and why do you ne...
Graal, Truffle, SubstrateVM and other perks: what are those and why do you ne...Graal, Truffle, SubstrateVM and other perks: what are those and why do you ne...
Graal, Truffle, SubstrateVM and other perks: what are those and why do you ne...
 
Как заводить баги понятно всем
Как заводить баги понятно всемКак заводить баги понятно всем
Как заводить баги понятно всем
 
мартюшев почему юнит-тесты не работают. история большого проекта
мартюшев   почему юнит-тесты не работают. история большого проектамартюшев   почему юнит-тесты не работают. история большого проекта
мартюшев почему юнит-тесты не работают. история большого проекта
 
Behavior Driven Development
Behavior Driven DevelopmentBehavior Driven Development
Behavior Driven Development
 

Viewers also liked

Understanding Date Handling and Collection Framework
Understanding Date Handling and Collection FrameworkUnderstanding Date Handling and Collection Framework
Understanding Date Handling and Collection Frameworkashishspace
 
Multithreading in java past and actual
Multithreading in java past and actualMultithreading in java past and actual
Multithreading in java past and actualYevgen Levik
 
Загрузчики классов в Java - коллекция граблей
Загрузчики классов в Java - коллекция граблейЗагрузчики классов в Java - коллекция граблей
Загрузчики классов в Java - коллекция граблейAnton Arhipov
 
Основы Java. 4. Collection Framework
Основы Java. 4. Collection FrameworkОсновы Java. 4. Collection Framework
Основы Java. 4. Collection FrameworkSergey Nemchinsky
 
Основы Java. 3. Конструкторы, уровни доступа, статика
Основы Java. 3. Конструкторы, уровни доступа, статикаОсновы Java. 3. Конструкторы, уровни доступа, статика
Основы Java. 3. Конструкторы, уровни доступа, статикаSergey Nemchinsky
 

Viewers also liked (7)

Understanding Date Handling and Collection Framework
Understanding Date Handling and Collection FrameworkUnderstanding Date Handling and Collection Framework
Understanding Date Handling and Collection Framework
 
Java 8. Thread pools
Java 8. Thread poolsJava 8. Thread pools
Java 8. Thread pools
 
Multithreading in java past and actual
Multithreading in java past and actualMultithreading in java past and actual
Multithreading in java past and actual
 
Загрузчики классов в Java - коллекция граблей
Загрузчики классов в Java - коллекция граблейЗагрузчики классов в Java - коллекция граблей
Загрузчики классов в Java - коллекция граблей
 
Основы Java. 4. Collection Framework
Основы Java. 4. Collection FrameworkОсновы Java. 4. Collection Framework
Основы Java. 4. Collection Framework
 
Основы Java. 3. Конструкторы, уровни доступа, статика
Основы Java. 3. Конструкторы, уровни доступа, статикаОсновы Java. 3. Конструкторы, уровни доступа, статика
Основы Java. 3. Конструкторы, уровни доступа, статика
 
SlideShare 101
SlideShare 101SlideShare 101
SlideShare 101
 

Similar to CodeFest 2014. Шипилёв А. — Java Benchmarking: как два таймстампа записать!

Железные счётчики на страже производительности
Железные счётчики на страже производительностиЖелезные счётчики на страже производительности
Железные счётчики на страже производительностиSergey Kuksenko
 
Занимательные истории из жизни технической поддержки JVM
Занимательные истории из жизни технической поддержки JVMЗанимательные истории из жизни технической поддержки JVM
Занимательные истории из жизни технической поддержки JVMNikita Lipsky
 
Continious integration-Automated Testing-Solid-Agile
Continious integration-Automated Testing-Solid-AgileContinious integration-Automated Testing-Solid-Agile
Continious integration-Automated Testing-Solid-AgileKairat Yussupov
 
Техники аналитика - CATWOE, H-METHOD, MOSCOW, SQUARE
Техники аналитика - CATWOE, H-METHOD, MOSCOW, SQUAREТехники аналитика - CATWOE, H-METHOD, MOSCOW, SQUARE
Техники аналитика - CATWOE, H-METHOD, MOSCOW, SQUARESQALab
 
Теория ограничений в Agile команде
Теория ограничений в Agile командеТеория ограничений в Agile команде
Теория ограничений в Agile командеyiiconf
 
Автоматизация тестирования - это пот, кровь и слезы
Автоматизация тестирования - это пот, кровь и слезы Автоматизация тестирования - это пот, кровь и слезы
Автоматизация тестирования - это пот, кровь и слезы Maxim Shulga
 
XP Days Ukraine 2014 - Refactoring legacy code
XP Days Ukraine 2014 - Refactoring legacy codeXP Days Ukraine 2014 - Refactoring legacy code
XP Days Ukraine 2014 - Refactoring legacy codeDmytro Mindra
 
kranonit S11E01 Андрей Пономарёв: Тренинг по TDD в Java
kranonit S11E01 Андрей Пономарёв: Тренинг по TDD в Javakranonit S11E01 Андрей Пономарёв: Тренинг по TDD в Java
kranonit S11E01 Андрей Пономарёв: Тренинг по TDD в JavaKrivoy Rog IT Community
 
Как сейчас тесты в Android пишут, Денис Неклюдов, Google Dev Expert, Москва
 Как сейчас тесты в Android пишут, Денис Неклюдов, Google Dev Expert, Москва  Как сейчас тесты в Android пишут, Денис Неклюдов, Google Dev Expert, Москва
Как сейчас тесты в Android пишут, Денис Неклюдов, Google Dev Expert, Москва it-people
 
Continuous Deployment (in Russian)
Continuous Deployment  (in Russian)Continuous Deployment  (in Russian)
Continuous Deployment (in Russian)Smartling
 
Dev & test на windows azure
Dev & test на windows azureDev & test на windows azure
Dev & test на windows azureMicrosoft
 
Continuous deployment Smartling event
Continuous deployment Smartling eventContinuous deployment Smartling event
Continuous deployment Smartling eventViktoriya Pridatko
 
Как сделать наши проекты немного более управляемыми с Agile
Как сделать наши проекты немного более управляемыми с AgileКак сделать наши проекты немного более управляемыми с Agile
Как сделать наши проекты немного более управляемыми с AgileAlexey Krivitsky
 
Разработка high load системы на .NET Core
Разработка high load системы на .NET CoreРазработка high load системы на .NET Core
Разработка high load системы на .NET CoreAndrew Gubskiy
 
ФРИИ интернет предпринимательство - Приложения и сервисы для бизнеса
ФРИИ интернет предпринимательство - Приложения и сервисы для бизнесаФРИИ интернет предпринимательство - Приложения и сервисы для бизнеса
ФРИИ интернет предпринимательство - Приложения и сервисы для бизнесаЭкосистемные Проекты Фрии
 
микроСЕРВИСЫ: огонь, вода и медные трубы
микроСЕРВИСЫ: огонь, вода и медные трубымикроСЕРВИСЫ: огонь, вода и медные трубы
микроСЕРВИСЫ: огонь, вода и медные трубыAleksandr Tarasov
 
Процесс изменения платформы Java
Процесс изменения платформы JavaПроцесс изменения платформы Java
Процесс изменения платформы JavaAlexey Fyodorov
 
Рефакторинг и второе рождение проекта на примере Zend Framework 2.0
Рефакторинг и второе рождение проекта на примере Zend Framework 2.0Рефакторинг и второе рождение проекта на примере Zend Framework 2.0
Рефакторинг и второе рождение проекта на примере Zend Framework 2.0AlexeyParhomenko
 

Similar to CodeFest 2014. Шипилёв А. — Java Benchmarking: как два таймстампа записать! (20)

Железные счётчики на страже производительности
Железные счётчики на страже производительностиЖелезные счётчики на страже производительности
Железные счётчики на страже производительности
 
Занимательные истории из жизни технической поддержки JVM
Занимательные истории из жизни технической поддержки JVMЗанимательные истории из жизни технической поддержки JVM
Занимательные истории из жизни технической поддержки JVM
 
Continious integration-Automated Testing-Solid-Agile
Continious integration-Automated Testing-Solid-AgileContinious integration-Automated Testing-Solid-Agile
Continious integration-Automated Testing-Solid-Agile
 
Техники аналитика - CATWOE, H-METHOD, MOSCOW, SQUARE
Техники аналитика - CATWOE, H-METHOD, MOSCOW, SQUAREТехники аналитика - CATWOE, H-METHOD, MOSCOW, SQUARE
Техники аналитика - CATWOE, H-METHOD, MOSCOW, SQUARE
 
Теория ограничений в Agile команде
Теория ограничений в Agile командеТеория ограничений в Agile команде
Теория ограничений в Agile команде
 
Автоматизация тестирования - это пот, кровь и слезы
Автоматизация тестирования - это пот, кровь и слезы Автоматизация тестирования - это пот, кровь и слезы
Автоматизация тестирования - это пот, кровь и слезы
 
XP Days Ukraine 2014 - Refactoring legacy code
XP Days Ukraine 2014 - Refactoring legacy codeXP Days Ukraine 2014 - Refactoring legacy code
XP Days Ukraine 2014 - Refactoring legacy code
 
kranonit S11E01 Андрей Пономарёв: Тренинг по TDD в Java
kranonit S11E01 Андрей Пономарёв: Тренинг по TDD в Javakranonit S11E01 Андрей Пономарёв: Тренинг по TDD в Java
kranonit S11E01 Андрей Пономарёв: Тренинг по TDD в Java
 
Как сейчас тесты в Android пишут, Денис Неклюдов, Google Dev Expert, Москва
 Как сейчас тесты в Android пишут, Денис Неклюдов, Google Dev Expert, Москва  Как сейчас тесты в Android пишут, Денис Неклюдов, Google Dev Expert, Москва
Как сейчас тесты в Android пишут, Денис Неклюдов, Google Dev Expert, Москва
 
Continuous Deployment (in Russian)
Continuous Deployment  (in Russian)Continuous Deployment  (in Russian)
Continuous Deployment (in Russian)
 
Dev & test на windows azure
Dev & test на windows azureDev & test на windows azure
Dev & test на windows azure
 
Continuous deployment Smartling event
Continuous deployment Smartling eventContinuous deployment Smartling event
Continuous deployment Smartling event
 
Как сделать наши проекты немного более управляемыми с Agile
Как сделать наши проекты немного более управляемыми с AgileКак сделать наши проекты немного более управляемыми с Agile
Как сделать наши проекты немного более управляемыми с Agile
 
Разработка high load системы на .NET Core
Разработка high load системы на .NET CoreРазработка high load системы на .NET Core
Разработка high load системы на .NET Core
 
Unit Testing
Unit TestingUnit Testing
Unit Testing
 
AUG-1
AUG-1AUG-1
AUG-1
 
ФРИИ интернет предпринимательство - Приложения и сервисы для бизнеса
ФРИИ интернет предпринимательство - Приложения и сервисы для бизнесаФРИИ интернет предпринимательство - Приложения и сервисы для бизнеса
ФРИИ интернет предпринимательство - Приложения и сервисы для бизнеса
 
микроСЕРВИСЫ: огонь, вода и медные трубы
микроСЕРВИСЫ: огонь, вода и медные трубымикроСЕРВИСЫ: огонь, вода и медные трубы
микроСЕРВИСЫ: огонь, вода и медные трубы
 
Процесс изменения платформы Java
Процесс изменения платформы JavaПроцесс изменения платформы Java
Процесс изменения платформы Java
 
Рефакторинг и второе рождение проекта на примере Zend Framework 2.0
Рефакторинг и второе рождение проекта на примере Zend Framework 2.0Рефакторинг и второе рождение проекта на примере Zend Framework 2.0
Рефакторинг и второе рождение проекта на примере Zend Framework 2.0
 

More from CodeFest

Alexander Graebe
Alexander GraebeAlexander Graebe
Alexander GraebeCodeFest
 
Никита Прокопов
Никита ПрокоповНикита Прокопов
Никита ПрокоповCodeFest
 
Денис Баталов
Денис БаталовДенис Баталов
Денис БаталовCodeFest
 
Елена Гальцина
Елена ГальцинаЕлена Гальцина
Елена ГальцинаCodeFest
 
Александр Калашников
Александр КалашниковАлександр Калашников
Александр КалашниковCodeFest
 
Ирина Иванова
Ирина ИвановаИрина Иванова
Ирина ИвановаCodeFest
 
Marko Berković
Marko BerkovićMarko Berković
Marko BerkovićCodeFest
 
Денис Кортунов
Денис КортуновДенис Кортунов
Денис КортуновCodeFest
 
Александр Зимин
Александр ЗиминАлександр Зимин
Александр ЗиминCodeFest
 
Сергей Крапивенский
Сергей КрапивенскийСергей Крапивенский
Сергей КрапивенскийCodeFest
 
Сергей Игнатов
Сергей ИгнатовСергей Игнатов
Сергей ИгнатовCodeFest
 
Николай Крапивный
Николай КрапивныйНиколай Крапивный
Николай КрапивныйCodeFest
 
Alexander Graebe
Alexander GraebeAlexander Graebe
Alexander GraebeCodeFest
 
Вадим Смирнов
Вадим СмирновВадим Смирнов
Вадим СмирновCodeFest
 
Константин Осипов
Константин ОсиповКонстантин Осипов
Константин ОсиповCodeFest
 
Raffaele Rialdi
Raffaele RialdiRaffaele Rialdi
Raffaele RialdiCodeFest
 
Максим Пугачев
Максим ПугачевМаксим Пугачев
Максим ПугачевCodeFest
 
Rene Groeschke
Rene GroeschkeRene Groeschke
Rene GroeschkeCodeFest
 
Иван Бондаренко
Иван БондаренкоИван Бондаренко
Иван БондаренкоCodeFest
 
Mete Atamel
Mete AtamelMete Atamel
Mete AtamelCodeFest
 

More from CodeFest (20)

Alexander Graebe
Alexander GraebeAlexander Graebe
Alexander Graebe
 
Никита Прокопов
Никита ПрокоповНикита Прокопов
Никита Прокопов
 
Денис Баталов
Денис БаталовДенис Баталов
Денис Баталов
 
Елена Гальцина
Елена ГальцинаЕлена Гальцина
Елена Гальцина
 
Александр Калашников
Александр КалашниковАлександр Калашников
Александр Калашников
 
Ирина Иванова
Ирина ИвановаИрина Иванова
Ирина Иванова
 
Marko Berković
Marko BerkovićMarko Berković
Marko Berković
 
Денис Кортунов
Денис КортуновДенис Кортунов
Денис Кортунов
 
Александр Зимин
Александр ЗиминАлександр Зимин
Александр Зимин
 
Сергей Крапивенский
Сергей КрапивенскийСергей Крапивенский
Сергей Крапивенский
 
Сергей Игнатов
Сергей ИгнатовСергей Игнатов
Сергей Игнатов
 
Николай Крапивный
Николай КрапивныйНиколай Крапивный
Николай Крапивный
 
Alexander Graebe
Alexander GraebeAlexander Graebe
Alexander Graebe
 
Вадим Смирнов
Вадим СмирновВадим Смирнов
Вадим Смирнов
 
Константин Осипов
Константин ОсиповКонстантин Осипов
Константин Осипов
 
Raffaele Rialdi
Raffaele RialdiRaffaele Rialdi
Raffaele Rialdi
 
Максим Пугачев
Максим ПугачевМаксим Пугачев
Максим Пугачев
 
Rene Groeschke
Rene GroeschkeRene Groeschke
Rene Groeschke
 
Иван Бондаренко
Иван БондаренкоИван Бондаренко
Иван Бондаренко
 
Mete Atamel
Mete AtamelMete Atamel
Mete Atamel
 

CodeFest 2014. Шипилёв А. — Java Benchmarking: как два таймстампа записать!

  • 1. Java Benchmarking как два таймстампа прочитать! Алексей Шипилёв aleksey.shipilev@oracle.com, @shipilev
  • 2. The following is intended to outline our general product direction. It is intended for information purposes only, and may not be incorporated into any contract. It is not a commitment to deliver any material, code, or functionality, and should not be relied upon in making purchasing decisions. The development, release, and timing of any features or functionality described for Oracle’s products remains at the sole discretion of Oracle. Slide 2/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 3. Введение Slide 3/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 4. Введение: В качестве разогрева «Сколько стоит создание одного String?» long startTime = System.nanoTime (); for (int i = 0; i < 1000; i++) { String s = new String(""); } long stopTime = System.nanoTime (); System.out.println("Time:" + (stopTime - startTime )); Slide 4/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 5. Теория Slide 5/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 6. Теория: Зачем люди делают бенчмарки? 1. Ради холивора: мой язык лучше твоего языка 2. Ради маркетинга: проверить, что мы вкладываемся в конкретные критерии 3. Ради инжиниринга: изолировать и зафиксировать перформансный феномен, чтобы была референсная точка для улучшения 4. Ради науки: понять, какой моделью описывается система, и на основании этой модели предсказать будущее поведение Slide 6/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 7. Теория: Ради холивора Прекрасный пример – Computer Language Benchmarks Game:1 Многие реализации вообще не сравнимы: e.g. AOT vs. JIT Измеряют непонятно что: e.g. pidigits измеряет скорость интерфейса до GMP Куча дисклеймеров про то, что в реальной жизни всё может быть по-другому: и тогда этот проект нужен только ради лулзов Любят его потому, что CLBG даёт числа, которыми можно размахивать в холиворах 1 http://benchmarksgame.alioth.debian.org/ Slide 7/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 8. Теория: Ради маркетинга Прекрасный пример – SPEC benchmarks: Референсные наборы бенчмарок, одинаково хороших/плохих для большинства вендоров Позволяют иметь референсные точки, против которых можно выставлять критерии успешности продукта, писать в рекламе и т.п. Ну и что, что они не всегда репрезентативны – главное, что они «золотые» Slide 8/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 9. Теория: Ради инжиниринга «If you can’t measure it, you can’t optimize it» Нужны лабораторные условия, в которых зафиксировано конкретное состояние системы, чтобы можно было проверять внесённые изменения Обычно фокусируются на конкретных местах продукта, имеют бОльшую разрешающую способность, чем маркетинговые бенчи Размеры и охват этих бенчмарков зависит от укуренности инженеров Slide 9/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 10. Теория: Ради науки «Science Town PD: To Explain and Predict» Извлечь из результатов тестов правдоподобную модель производительности Из модели получить предсказания о будущем поведении, проверить эти предсказания, спокойно вздохнуть и деплойнуть в прод Самая трудоёмкая, и самая надёжная цель бенчмаркинга Slide 10/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 11. Теория: Что интересно нам? 1. Ради холивора: мой язык лучше твоего языка 2. Ради маркетинга: проверить, что мы вкладываемся в конкретные критерии 3. Ради инжиниринга: изолировать и зафиксировать перформансный феномен, чтобы была референсная точка для улучшения 4. Ради науки: понять, какой моделью описывается система, и на основании этой модели предсказать будущее поведение Slide 11/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 12. Теория: Бенчмарки – это эксперименты Хорошие эксперименты отвечают на несколько групп вопросов: 1. Что измеряем: какие метрики используем? Что эти метрики нам говорят? 2. Как измеряем: какими способами мы измеряем метрики? какая точность у этих способов? какие подводные камни? 3. Как проверяем: как поверяем наши инструменты? как узнаём, что результатам можно доверять? Slide 12/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 13. Что измеряем: Метрики Две главные группы метрик: Bandwidth (𝜆) Сравнительно легко измерить Легко вводится в steady state Скрывает большие задержки Упускает active-idle Latency (𝜏) Трудно измерить корректно Средняя latency как правило бессмыслена Нужно считать квантили Семплы меньше 1мкс получить не практично Slide 13/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 14. Что измеряем: путаем bandwidth и latency Отличия в нагрузке: – 𝜆 обычно измеряют под пиковой нагрузкой – 𝜏 как правило измеряют под регулируемой нагрузкой – Нагрузка – это новая степень свободы! Отличия в подходах к измерению: – Средняя задержка – бессмысленная метрика, ибо 𝜏 𝑎𝑣𝑔 = 1 𝜆 – Нужно мерить каждое событие, и считать квантили! – События короче 1 мкс? Мухаха. Slide 14/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 15. Что измеряем: 𝜆 и 𝜏 – братья навек Slide 15/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 16. Как измеряем: типы бенчмарок Два главных подхода: Time-based Исполняем постоянное время Делаем операции одну за одной В измерение умещаем порядочное количество операций Fixed work Исполняем постоянное количество операций Чаще всего одну операцию Здорово экономит время! Slide 16/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 17. Как измеряем: Transients Запомните Мы имеем дело с динамическими системами. «Прогрев» – это выжидание характерного времени переходного процесса. У нас полно переходных процессов. Slide 17/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 18. Как измеряем: Transients Запомните Мы имеем дело с динамическими системами. «Прогрев» – это выжидание характерного времени переходного процесса. У нас полно переходных процессов. Компиляция кода – не единственный переходный процесс! Slide 17/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 19. Как измеряем: Transients Запомните Мы имеем дело с динамическими системами. «Прогрев» – это выжидание характерного времени переходного процесса. У нас полно переходных процессов. Компиляция кода – не единственный переходный процесс! «Мудрость»: «Cледите за PrintCompilation». WTF? Slide 17/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 20. Как измеряем: Steady state Система пришла в устойчивое состояние (steady state), когда все её переходные процессы устканились Любое изменение выбивает её из steady state Slide 18/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 21. Как измеряем: Иногда steady state нет! public class FibonacciGen { BigInteger n1 = ONE; BigInteger n2 = ZERO; public BigInteger next () { BigInteger cur = n1.add(n2); n2 = n1; n1 = cur; return cur; } } Каждый вызов next() всё медленней и медленней Имеет смысл измерять первые N операций – а там transients! Slide 19/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 22. Как проверяем: Инженерный подход Главный инженерный вопрос Почему мой бенчмарк не может работать быстрее? Ответ определяет качество эксперимента: 1. В какие ограничения упёрлись? 2. Работает та часть кода, которую мы «исследуем»? 3. Что сделать, чтобы исправить бенчмарк? Slide 20/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 23. Как проверяем: Научный подход Главный научный вопрос Как бенчмарк реагирует на изменение внешних условий? Отвечаем, насколько актуальная модель разнится с ментальной: 1. Проверка на дурака: имеют ли смысл эти результаты? 2. Негативный контроль: меняется ли результат от варирования переменной 𝑋𝑖, хотя не должен? 3. Позитивный контроль: не меняется ли результат от варирования переменной 𝑌𝑖, хотя должен? Slide 21/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 24. Практика Slide 22/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 25. Практика: JMH У нас тоже есть очень хороший харнесс: http://openjdk.java.net/projects/code-tools/jmh/ JMH is Serious Business: – Он учитывает тонну VM-ных эффектов – Мы его периодически допиливаем, когда меняется VM – Мы его периодически фиксим, как растёт наша экспертиза – Всякий внешний бенч валидируется переписыванием под JMH Slide 23/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 26. Практика: JMH У нас тоже есть очень хороший харнесс: http://openjdk.java.net/projects/code-tools/jmh/ JMH is Serious Business: – Он учитывает тонну VM-ных эффектов – Мы его периодически допиливаем, когда меняется VM – Мы его периодически фиксим, как растёт наша экспертиза – Всякий внешний бенч валидируется переписыванием под JMH Мы вынули столько неочевидных граблей из JMH, что не верим ни одному известному харнессу. Slide 23/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 27. Практика: Цель Цель всего этого мероприятия в том, чтобы вас как следует напугать и заставить бросить: (тупо) писать обёртки для бенчмарок (тупо) доверять обёрткам для бенчмаркок (тупо) доверять бенчмаркам Slide 24/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 28. System: Задачка (A) Давайте запустим простенький бенчмарк. Система говорит, что у неё 4 CPU. Threads Ops/nsec Scale 1 3.06 ± 0.10 2 5.72 ± 0.10 1.87 ± 0.03 4 5.87 ± 0.02 1.91 ± 0.03 Slide 25/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 29. System: Задачка (A) Давайте запустим простенький бенчмарк. Система говорит, что у неё 4 CPU. Threads Ops/nsec Scale 1 3.06 ± 0.10 2 5.72 ± 0.10 1.87 ± 0.03 4 5.87 ± 0.02 1.91 ± 0.03 Вопрос 1: Почему переход 2 → 4 потока такой хилый? Slide 25/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 30. System: Задачка (A) Давайте запустим простенький бенчмарк. Система говорит, что у неё 4 CPU. Threads Ops/nsec Scale 1 3.06 ± 0.10 2 5.72 ± 0.10 1.87 ± 0.03 4 5.87 ± 0.02 1.91 ± 0.03 Вопрос 1: Почему переход 2 → 4 потока такой хилый? Вопрос 2: Почему переход 1 → 2 потока всего 1.87x? Slide 25/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 31. System: Power management Запускаем простой бенчмарк, + и зажимаем частоту CPU в 2 GHz: Threads Ops/nsec Scale 1 1.97 ± 0.02 2 3.94 ± 0.05 2.00 ± 0.02 4 4.03 ± 0.04 2.04 ± 0.02 Slide 26/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 32. System: Power management Многие подсистемы балансируют power-vs-performance (Ex.: cpufreq, SpeedStep, Cool&Quiet, TurboBoost) Засада: ломает гомогенность времени Костыль: выключить PM, зажать частоту CPU JMH: работаем дольше, не паркуем потоки Slide 27/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 33. System: OS Schedulers Шедулеры OS балансируют affinity-vs-power (Ex.: Solaris schedulers, Linux power-efficient taskqueues) Засада: ломает иллюзию симметричности CPU Костыль: зажать политики шедулинга JMH: работаем дольше, не паркуем потоки Slide 28/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 34. System: Time Sharing Системы разделяемого времени балансируют утилизацию. (Ex.: тысячи их) Засада: старт/останов потоков не мгновенный, время работы потоков не детерминировано, загрузка во времени неоднородна Костыль: удостовериться, что все потоки начали исполнять работу JMH: «synchronize iterations» Slide 29/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 35. System: Time Sharing, #2 JMH – synchronize iterations: Slide 30/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 36. System: Time Sharing, Quiz (B) public void measure () { long startTime = System.nanoTime (); while (! isDone) { work (); } println(System.nanoTime () - startTime ); } Slide 31/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 37. System: Time Sharing, Задачка (B) «Is there a problem, officer?» public void measure () { long realTime = 0; while (! isDone) { setup (); // skip this long time = System.nanoTime (); work (); realTime += (System.nanoTime () - time ); } println(realTime ); } Slide 32/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 38. System: Time Sharing, Задачка (B) Измеряем количество вызовов в секунду, да? 0 200 400 600 0 10 20 30 # Threads throughput,ops/us Timing the entire loop Timing the sum[iterations] ...а оно растёт за количество CPU – WTF?! Slide 33/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 39. System: Time Sharing, Задачка (B) public void measure () { long startTime = System.nanoTime (); long realTime = 0; while (! isDone) { setup (); // skip this long time = System.nanoTime (); work (); realTime += (System.nanoTime () - time ); ...WHOOPS, WE DE-SCHEDULE HERE... } println(realTime ); println(System.nanoTime () - startTime ); } Slide 34/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 40. System: Time Sharing Разделение времени даёт иллюзию параллельной работы нескольких потоков Засада: эта иллюзия не всегда выполняется для производительности! Костыль: никогда не перегружать систему! JMH: большой красный флаг на въезде в страну Slide 35/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 41. VM: Задачка (C) @GenerateMicroBenchmark public void baseline () { } 0.5 ± 0.1 ns @GenerateMicroBenchmark public void measureWrong () { Math.log(x); } 0.5 ± 0.1 ns @GenerateMicroBenchmark public double measureRight () { return Math.log(x); } 34.0 ± 1.0 ns Slide 36/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 42. VM: Dead-code elimination Оптимизаторы очень хорошо удаляют код без наблюдаемых эффектов. Засада: может снести часть бенчмарка вдрабадан Костыль: наводим эффекты на результаты (суммируем, складываем, печатаем, и т.п.) JMH: поддержка в API Slide 37/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 43. VM: Задачка (D) @GenerateMicroBenchmark public void baseline () { } 0.5 ± 0.1 ns @GenerateMicroBenchmark public double measureWrong () { return Math.log (42); } 1.0 ± 0.1 ns private double x = 42; @GenerateMicroBenchmark public double measureRight () { return Math.log(x); } 34.0 ± 1.0 ns Slide 38/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 44. VM: Constant folding, etc. Оптимизаторы довольно хороши в предвычислениях. Засада: может предоптимизировать часть бенчмарка Костыль: сделать входные данные непредсказуемыми JMH: поддержка в API Slide 39/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 45. VM: CSE JMH ломает спекуляцию о чтениях в разных вызовах @GMB метода double x; @GenerateMicroBenchmark double doWork () { doStuff(x); } volatile boolean done; void doMeasure () { while (! done) { doWork (); } } (Перевод: читаем всё из кучи ⇒ мы спасены!) Slide 40/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 46. VM: DCE, CSE... одно и то же! Потеря непредсказуемости что источника, что результата теряет и часть бенчмарка. Тихо и незаметно. Slide 41/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 47. VM: DCE, CSE... одно и то же! Потеря непредсказуемости что источника, что результата теряет и часть бенчмарка. Тихо и незаметно. Slide 41/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 48. VM: DCE, CSE... одно и то же! Потеря непредсказуемости что источника, что результата теряет и часть бенчмарка. Тихо и незаметно. Slide 41/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 49. VM: Задачка (E) // changing N, will performance differ? static int N = 100; @GenerateMicroBenchmark public int test () { return doWork(N); } int x = 1, y = 2; private int doWork(int reps) { int s = 0; for (int i = 0; i < reps; i++) s += (x + y); return s; } Slide 42/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 50. VM: Задачка (E), #2 N ns/call ns/add 1 1.5 ± 0.1 1.5 ± 0.1 10 2.0 ± 0.1 0.1 ± 0.01 100 2.7 ± 0.2 0.05 ± 0.02 1000 68.8 ± 0.9 0.07 ± 0.01 10000 410.3 ± 2.1 0.04 ± 0.01 100000 3836.1 ± 40.6 0.04 ± 0.01 Slide 43/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 51. VM: Задачка (E), #2 N ns/call ns/add 1 1.5 ± 0.1 1.5 ± 0.1 10 2.0 ± 0.1 0.1 ± 0.01 100 2.7 ± 0.2 0.05 ± 0.02 1000 68.8 ± 0.9 0.07 ± 0.01 10000 410.3 ± 2.1 0.04 ± 0.01 100000 3836.1 ± 40.6 0.04 ± 0.01 Ну и какой строчке верить? 0.04 ns/add ⇒ 25 adds/ns ⇒ GTFO! Slide 43/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 52. VM: Loop unrolling Раскрутка циклов сильно расширяет диапазон оптимизаций. Засада: положим, одна итерация цикла занимает 𝑀 нс. Тогда после раскрутки цикла она эффективно занимает 𝛼𝑀 ns, где 𝛼 ∈ [0; +∞) Костыль: избегаем раскручиваемых циклов, минимизируем эффекты от раскрутки JMH: оказывается, что костыли для CSE/DCE так же ломают эффекты от раскрутки Slide 44/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 53. VM: Задачка (F) interface M { void inc (); } abstract class AM implements M { int c; void inc() { c++; } } class M1 extends AM {} class M2 extends AM {} Slide 45/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 54. VM: Задачка (F), #2 M m1 = new M1(); M m2 = new M2(); @GenerateMicroBenchmark public void testM1 () { test(m1); } @GenerateMicroBenchmark public void testM2 () { test(m2); } void test(M m) { for (int i = 0; i < 100; i++) m.inc (); } Slide 46/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 55. VM: Задачка (F), #3 test ns/op testM1 4.6 ± 0.1 testM2 36.0 ± 0.4 Slide 47/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 56. VM: Задачка (F), #3 test ns/op testM1 4.6 ± 0.1 testM2 36.0 ± 0.4 repeat testM1 35.8 ± 0.4 Slide 47/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 57. VM: Задачка (F), #3 test ns/op testM1 4.6 ± 0.1 testM2 36.0 ± 0.4 repeat testM1 35.8 ± 0.4 forked testM1 4.5 ± 0.1 forked testM2 4.5 ± 0.1 Slide 47/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 58. VM: Profile feedback Динамические оптимизации могут использовать информацию времени исполнения (Ex.: call profile, type profile, CHA info) Засада: Серьёзная разница между режимами «всё в одной VM» и «всё в отдельных VM» Костыль: Прогреваем все бенчмарки вместе, ИЛИ запускаем каждый бенчмарк в отдельной JVM JMH: поддержка bulk warmup; forking Slide 48/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 59. VM: Задачка (G) Slide 49/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 60. VM: Задачка (G), #2 Slide 50/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 61. VM: Run-to-run variance Многие масштабируемые алгоритмы не детерминированы! (Ex.: memory allocators, profiler counters, non-fair locks, concurrent data structures, ...) Засада: (потенциально) (огромная) разница между запусками в одной конфигурации Костыль: протоколирование решений на каждом уровне (e.g. запись решений компилятора), несколько запусков JVM JMH: несколько запусков JVM Slide 51/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 62. VM: Inlining budgets Подстановка (inlining) – это убер-оптимизация Засада: Всё заинлайнить нельзя ⇒ приходится думать о том, что инлайнится, а что нет Костыль: Методы мельче, циклы мельче, подглядываем в -XX:+PrintInlining, используем компиляторные хинты JMH: генерируем горячие циклы в мелкие методы, даём удобный @CompileControl Slide 52/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 63. VM: сгенерированный JMH код JIT-компиляция и подстановки начинаются с этого метода: public void testLong_loop (Loop loop , Result r, MyBenchmark bench) { long ops = 0; r.start = System.nanoTime (); do { bench.testLong (); // @GenerateMicroBenchmark ops ++; } while (! loop.isDone ); r.end = System.nanoTime (); r.ops = ops; } Slide 53/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 64. CPU: Задачка (H) @State public class TreeMapBench { Map <String , String > map = new TreeMap <>(); @Setup public void setup () { populate(map); } @GenerateMicroBenchmark public void test(BlackHole bh) { for(String key : map.keySet ()) { String value = map.get(key); bh.consume(value ); } } }Slide 54/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 65. CPU: Задачка (H), #2 @GenerateMicroBenchmark public void test(BlackHole bh) { for(String key : map.keySet ()) { String value = map.get(key); bh.consume(value ); } } Exclusive Shared Throughput, op/sec 615 ± 12 828 ± 21 Slide 55/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 66. CPU: Задачка (H), #2 @GenerateMicroBenchmark public void test(BlackHole bh) { for(String key : map.keySet ()) { String value = map.get(key); bh.consume(value ); } } Exclusive Shared Throughput, op/sec 615 ± 12 828 ± 21 Threads 4 4 Slide 55/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 67. CPU: Задачка (H), #2 @GenerateMicroBenchmark public void test(BlackHole bh) { for(String key : map.keySet ()) { String value = map.get(key); bh.consume(value ); } } Exclusive Shared Throughput, op/sec 615 ± 12 828 ± 21 Threads 4 4 Maps 4 1 Slide 55/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 68. CPU: Задачка (H), #2 @GenerateMicroBenchmark public void test(BlackHole bh) { for(String key : map.keySet ()) { String value = map.get(key); bh.consume(value ); } } Exclusive Shared Throughput, op/sec 615 ± 12 828 ± 21 Threads 4 4 Maps 4 1 Footprint, Kb 1024 256 Slide 55/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 69. CPU: Cache capacity Основная память слишком далека. Давайте кешировать всё прямо в проце! Засада: Производительность заметно отличается в зависимости от футпринта, путей обхода памяти, да и банальной удачи Костыль: Следим за футпринтом; пробуем разные размеры данных; пробуем разные shared/unshared случаи JMH: @State sharing Slide 56/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 70. CPU: Задачка (I) Насколько хорошо скалируется этот код? @State(Scope.Benchmark) class Shared { final int[] c = new int [64]; } @State(Scope.Thread) class Local { static final AtomicInteger COUNTER = ...; final int index = COUNTER.incrementAndGet (); } @GenerateMicroBenchmark void work(Shared s, Local l) { s.c[l.index ]++; }Slide 57/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 71. CPU: Задачка (I), #2 Threads Average ns/call Hit 1 2.0 ± 0.1 2 18.5 ± 2.4 9x 4 32.9 ± 6.2 16x 8 85.4 ± 13.4 42x 16 208.9 ± 52.1 104x 32 464.2 ± 46.1 232x Почему? Slide 58/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 72. CPU: Bulk method transfers Система следит за когерентностью памяти по кусочкам. Характерный размер кусочка: 32, 64, 128 байта. Засада: модификация рядом лежащих данных разными потоками даётся с трудом (false sharing) Костыль: паддинг, subclass juggling, @Contended JMH: все внутренние структуры отпажжены, @State-объекты паддятся автоматически Slide 59/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 73. CPU: Задачка (J)2 Exhibit B. Exhibit P. int sum = 0; for (int x : a) { if (x < 0) { sum -= x; } else { sum += x; } } return sum; int sum = 0; for (int x : a) { sum += Math.abs(x); } return sum; Которая версия быстрее? 2 Credits: Sergey Kuksenko (@kuksenk0) Slide 60/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 74. CPU: Задачка (J) E. Branched E. Predicated L0: mov 0xc(%ecx ,%ebp ,4) ,% ebx test %ebx,%ebx jl L1 add %ebx ,% eax jmp L2 L1: sub %ebx ,% eax L2: inc %ebp cmp %edx ,% ebp jl L0 L0: mov 0xc(%ecx ,%ebp ,4) ,% ebx mov %ebx ,%esi neg %esi test %ebx ,% ebx cmovl %esi,%ebx add %ebx ,%eax inc %ebp cmp %edx ,%ebp jl Loop Которая версия быстрее? Slide 61/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 75. CPU: Задачка (J) Regular Pattern = (+, –)* NHM Bldzr C-A9 SNB branch_regular 0.9 0.8 5.0 0.5 branch_shuffled 6.2 2.8 9.4 1.0 branch_sorted 0.9 1.0 5.0 0.6 predicated_regular 2.0 1.0 5.3 0.8 predicated_shuffled 2.0 1.0 9.3 0.8 predicated_sorted 2.0 1.0 5.7 0.8 time, nsec/op Slide 62/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 76. CPU: Branch Prediction Out-of-Order процессоры очень много спекулируют. Большую часть времени (99%+) делают это корректно! Засада: Провал в производительности, когда спекуляция проваливается Костыль: Реалистичные данные! Много, много разных наборов данных Slide 63/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 77. Выводы Slide 64/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 78. Выводы: Benchmarking is Serious Business Огромное поле для ошибок. Написание тестов требует экспертизы Написание фреймворков требует ещё большей экспертизы Не верьте красивым репортам, верьте логичным результатам Slide 65/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 79. Выводы: инструменты 1. Мозг – Плагин «данунеможетбыть» для перепроверок фактов – Плагин «щапридумаем» для построения гипотез и экспериментов – Плагин «чётоянепонял» для проверки консистентности гипотез – Плагин «ядурак» для лёгкого отвержения ложных гипотез 2. Руки – Прямые, для постановки аккуратных экспериментов – Сильные, для обработки тонн экспериментальных данных 3. Язык, уши, глаза и прочее I/O – Для обмена результатами и peer review – Для доступа к предыдущим экспериментам Slide 66/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.
  • 80. Выводы: прочие инструменты 1. Фреймворки – JMH: http://openjdk.java.net/projects/code-tools/jmh/ 2. Профилировщики – VisualVM, JRockit Mission Control, Oracle Studio Performance Analyzer – top, vmstat, mpstat, iostat, dtrace, strace 3. Дизассемблеры – -XX:+PrintAssembly – https: //wikis.sun.com/display/HotSpotInternals/PrintAssembly Slide 67/67. Copyright c○ 2013, Oracle and/or its affiliates. All rights reserved.