Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Потребляемое время для jvm-стратегий #106

Open
dbf256 opened this issue Dec 13, 2020 · 5 comments
Open

Потребляемое время для jvm-стратегий #106

dbf256 opened this issue Dec 13, 2020 · 5 comments

Comments

@dbf256
Copy link

dbf256 commented Dec 13, 2020

На данный момент стратегии для jvm-языков испытывают проблемы с доступным процессорным временем.

Например:

  1. Java: https://russianaicup.ru/game/view/191830# - время выводится каждые 100 тиков, после 600 потрачено 3744мс, по тестирующей системе 13001
  2. Java: https://russianaicup.ru/game/view/188119# - после 800 тиков внутри стратегии потрачено 6187ms, по тестирующей системе 21037.

Это не может быть накладными расходами на сеть/распаковку/перепаковку входных данных, т.к. вот пример игры на 1000 тиков, где используемое Java время составило < 6 секунд https://russianaicup.ru/game/view/1865#

Это приводит к следующим проблемам:

  1. Стратегия получает значительно меньше 40 секунд
  2. Это не какой-то фиксированный штраф (например, 5 секунд), который можно заложить с некоторым запасом и понимать сколько времени доступно. В таких условиях невозможно реализовывать алгоритмы с перебором и отсечением по времени.

По результатам некоторых исследований кажется, что это не GC (лог показывает, что он срабатывает совсм не каждый тик и занимает миллисекунды), а скорее что-то с jit-компилятором, который, возможно из-за работы в фоне (тем более, если доступны несколько ядер) может тратить много процессорного времени.
Если это так, то, вероятно, для запуска стратегий для соревнований лучше его как-то сконфигурировать, чтобы уменьшить потребляемое им время.

@DragoonXen
Copy link

DragoonXen commented Dec 13, 2020

Варианты, которые могут помочь:

  1. 1 стратегия - не больше 1 ядра CPU
  2. Конфигурация jit. Например (может быть актуально не для любой имплементации java, надо проверять в докере):
  • -XX:-TieredCompilation -XX:CICompilerCount=1 - уменьшит агрессивность оптимизатора, который будет работать в 1 поток
  • дополнительно -XX:CompileThreshold=[20000|50000|100000] - увеличит необходимое кол-во запусков функции до оптимизации (слишком больше число и Java становится интерпретатором как питон)
  • -XX:-TieredCompilation -XX:-BackgroundCompilation - опасная вещь - отключает оптимизации jit в бэкграунд потоках. Стратегия теперь +- понимает, сколько времени ест, однако есть БОЛЬШОЙ риск вылететь за ограничение в 1 секунду на тик хода из-за jit оптимизаций прямо во время обсчётов
  • -Xint - приравнивает java к python :-)

@azu0nyan
Copy link

azu0nyan commented Dec 13, 2020

Было бы неплохо хотябы убрать ограничение в 1 секунду на первый тик.
Например тут https://russianaicup.ru/game/view/196345
В первый тик отваливается стратегия потаймауту из-за jit. Мой подсчет показывает 800ms на тик, а в последующие тики, когда jit все собрал, стратегия работает за < 20 ms.
Это при том что у меня в коде написано if(currentTick == 0) {Делаем намного меньше чем в другие тики}
Если пережить первый тик, то стратегия нормально доигрывает до конца без ТЛЕ как тутhttps://russianaicup.ru/game/view/195830

@Karloid
Copy link

Karloid commented Dec 13, 2020

Так же наблюдаю проблему, стратегия замеряет потребление в ~7сек за матч от старта парсинга, до выдачи ответа, а система видит 30-40сек + таймлимиты

TLDR: кажется с флагами -XX:-TieredCompilation -XX:CompileThreshold=20000 -XX:CICompilerCount=1 заметно лучше (в 1.5\2 раза) и надо бы их добавить на сайте

Сделал замеры на jdk11 варианта без флагов (как на сайте)

 % sh ./runLrBatch4QuickStart.sh && time java -jar ./0_cur.jar

499 tickTook=1 globalTimeConsumed=860 segmentTimeConsumed=128 - игра занимает 500-700 тиков против QuickStart

java -jar ./0_cur.jar  12.32s user 0.20s system 187% cpu 6.661 total

java_no_flags
~550 тиков, 12.32s - CPU тайма и ~1c засеченного времени
в профиле на другой экземпляр матча так же видим что стратегия занимает +- 10% от всего времени


матч флагами -XX:-TieredCompilation -XX:CompileThreshold=20000 -XX:CICompilerCount=1
показывает лучшие результаты в ~1.5 раза

% sh ./runLrBatch4QuickStart.sh && time java -jar -XX:-TieredCompilation -XX:CompileThreshold=20000 -XX:CICompilerCount=1 ./0_cur.jar

599 tickTook=1 globalTimeConsumed=1459 segmentTimeConsumed=146
java -jar -XX:-TieredCompilation -XX:CompileThreshold=20000  ./0_cur.jar  6.94s user 0.14s system 91% cpu 7.693 total

java_jit_flags

650 тиков, 7s - CPU тайма и ~1.55s засеченного времени
в итоге игра вышла дольше на ~100 тиков, но общего CPU времени потратила меньше почти в два раза.

PS: попробую еще запустить с AOT компиляцией в нативный бинарник в GraalVm

@Karloid
Copy link

Karloid commented Dec 13, 2020

Попробовал скомпилировать бинарник с помощью GraalVM native-image
результат очень хороший

% native-image -jar ./0_cur.jar ./0_cur_native 

% sh ./runLrBatch4QuickStart.sh && time ./0_cur_native
499 tickTook=2 globalTimeConsumed=1108 segmentTimeConsumed=197
./0_cur_native  1.16s user 0.07s system 19% cpu 6.438 total

~550тиков, 1.16s CPU time и ~1.15s засеченного времени внутри стратегии
(напомню результат с настройками запуска с сайта - ~550 тиков, 12.32s - CPU тайма и ~1c засеченного времени )

т.е. проблемы с JIT нет, все время отводится стратегии, скорость не пострадала.

Выглядит как мастхев, попробую разобраться с докером+граальVm и собрать ПР

@Karloid
Copy link

Karloid commented Dec 17, 2020

Можно закрывать, смерджили ПР с граалем, на нем с производительностью все гораздо лучше становится

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants