Избранные места из переписки
Андрей Климов :
Большое спасибо! Надо же: и суперкомпилятор Явы, оказывается, уже способен на что-то содержательное... ;-)
Как я понял, это еще не такие фокусы, как удается делать с ScpR, но все-таки...
Александр Корлюков :
Теперь "плохие" новости про этот пример.
Отправив письмо, решил посмотреть, как ведет себя суперкомпилятор на примерах побольше. Я вручную менял переменную dim в начале программы.
Обнаружилось, что при больших dim времена исполнения не в нашу пользу.
dim = 11. Время до суперкомпиляции - 8.2 сек, после - 18.7 сек. Размер программы - 46 К.
dim = 13. Время до суперкомпиляции - 13.2 сек, после - 31.9 сек. Размер программы - 71 К. Суперкомпиляции заняла полчаса.
Аркадий Климов :
Интересно, а есть ли этому какие-то объяснения, гипотезы. У меня есть одна, она связана с автоматическим jit-компилятором.
Это такая штука, которая на лету (just-in-time) компилирует байткод в прямой код машины. Она делает это не с любым кодом, а только с таким, который выполняется не впервые (а может после какой-то итерации). Кроме того, я не знаю, работает ли она по-методно или еще как. В нашем случае длина кода программы растет примерно как куб (или может больше) параметра. И этот увеличенный код подвергается еще и компиляции - и все это внутри измеряемого времени.
Чтобы отделаться от этого эффекта я предлагаю фрагмент кода с изменением и выводом времени заключить еще в один цикл, который выполнять 5 раз. Тогда на распечатке будет не одно время, а 5 времен.
Я проделал это для dim=7 и увидел, что времена выглядят примерно так:
До суперкомпиляции:
Total time = 2.613
Total time = 2.324
Total time = 2.313
Total time = 2.323
Total time = 2.344
После суперкомпиляции
Total time = 1.422
Total time = 0.601
Total time = 0.55
Total time = 0.551
Total time = 0.551
Таким образом, если откинуть первое исполнение, то ускорение получается не в 2 раза, а в 4 !
Ну, а теперь интересно, что будет происходить при больших dim.
PS. Существенно, какая используется java-машина. Я использую sun-овскую из JDK1.3 и всем советую делать то же. А MS-овскую использовать для измерений - дело гиблое: ничего нельзя ни предсказать, ни объяснить.
PPS. Другой метод - вообще отключить jit-компиляцию. Для этого нужно указать ключ -Xint (у команды java) Я попробовал на том же примере, получились времена 28 и 6.5 соответственно, которые не зависят от повторения. Те же 4 раза.
PPPS. А чтобы узнать про этот ключ нужно вызвать java -X.
Александр Корлюков.
С точки зрения суперкомпиляции - пример очень хорош. Первый участок программы, где происходит вычисление магического квадрата, - полностью сворачивается. На втором участке из четырех вложенных циклов остается лишь один.
В этом тексте - программа немного переделана. Плюс итоговая таблица.
Все бы было нормально, если не размерность 13 (наверное таково число :-) ). -Xint у меня никак не действует или я не так им пользуюсь.
dim | время до суперкомпиляции | время после суперкомпиляции | коэффицент ускорения | |
3 | 0.14 | 0.3 | 4.6 | |
5 | 0.67 | 0.12 | 5.5 | |
7 | 1.6 | 0.29 | 5.4 | |
9 | 3.16 | 0.6 | 5.3 | |
11 | 5.5 | 1.1 | 5.0 | |
13 | 8.8 | 30.5 | 0.3 |
Попробовал еще dim=15. 45 минут суперкомпиляции, 100К результирующей программы, все хорошо работает, но времена не в нашу пользу - 14сек и 45 сек.(этот пример не посылаю, только времена).
Андрей Климов.
Очень странный срыв на 13... Коэффициенты до 11 выглядят ровно -- и вдруг!
У меня совсем нет каких-либо идей, что бы это значило (кроме времени работы JIT, которое ты, по-видимому, отсекаешь предварительными циклами).
Никаких идей?
Александр Корлюков
D:\Korl\Windows98\Old03\MagicSquare>java -version
java version "1.3.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-C)
Java HotSpot(TM) Client VM (build 1.3.0-C, mixed mode)
Это такая у меня версия.
Теперь пробую -Xint
dim=15 (цикл 5 раз по 10000 итераций)
Вариант до суперкомпиляции
без -Xint
Total time = 1.422
Total time = 1.342
Total time = 1.332
Total time = 1.332
Total time = 1.341
с -Xint
Total time = 16.374
Total time = 16.393
Total time = 16.374
Total time = 16.363
Total time = 16.404
Вариант после суперкомпиляции
без -Xint
Total time = 4.377
Total time = 4.386
Total time = 4.376
Total time = 4.3870000000000005
Total time = 4.386
с -Xint
Total time = 4.316
Total time = 4.306
Total time = 4.306
Total time = 4.316
Total time = 4.307
Аркадий Климов
Похоже, все понятно.
Если отключить JIT (-Xint), то таблица получается почти однородной: ускорение где-то в 4-5 раз. А в режиме с JIT он срабатывает не всегда, в частности, не срабатывает при очень больших методах - возможно, там стоит предохранитель. Видно, что даже какое-то лишнее время уходит на его работу.
Потому и получается "не в нашу пользу". Мораль: большие методы делать вредно.
Хотя понятно, что эта "мораль" не в нашу пользу. Возможно, придется разбираться с этим предохранителем.