Здравствуйте, Pzz, Вы писали:
Pzz>Отличие от JIT, насколько я понимаю, заключается лишь в том, что AOT сохраняет результаты компиляции на диск? Т.е., при повторном запуске не надо еще раз перекомпилировать?
Pzz>Однако, не из чего не следует, что качество кода при использовании этой технологии лучше, чем у JIT.
В локальных оптимизациях JIT находится не в худшей ситуации, чем обычный компилятор. Разве что у него жесткие рамки на скорость самой компиляции. А вот в плане глобальных оптимизаций у него есть преимущества. Вот только что на ЛОРе я приводил тест (впрочем, лажовый тест, не для этого сайта), который в цикле вызывал функцию, подключенную динамической линковкой в случае C (вызов из .so) и динамической загрузкой класса в случае Java + вызов по интерфейсу (что на самом деле еще более "динамический" случай, в последнем примере имплементация вообще по HTTP грузилась).
Так вот Java просто взяла и заинлайнила виртуальный вызов по интерфейсу и порвала по скорости C-шный вариант, который честно вызывал функцию по указателю. А у Bartok-а еще больше преимуществ. Во-первых, это AOT, можно особо не торопиться и покорпеть над оптимизациями. А во-вторых, новый код подгружать нельзя -- можно инлайнить не заморачиваясь. Java же вынуждена отслеживать моменты, когда эта оптимизация перестает быть валидной и переоптимизировать код.
Здравствуйте, Pzz, Вы писали: Pzz>Я в принципе считаю статический контроль невредным изобретением. Позволяющим поймять многие типичные ошибки. В общем, развитие темы warning'ов в компиляторе. Но никакие warning'и не дают вам 100%-й гарантии надежности, а именно она нужна при отказе от защиты памяти времени исполнения.
Singularity дает 100% гарантию надежности. В чем проблема?
НС>>Сингуларити на многих операциях быстрее обычных ОС. Как раз из-за отсутствия аппаратной защиты. Pzz>Существует масса экспериментальных ОС, которые прекрасно справляются с исследовательскими задачами в условиях лаборатории. К сожалению, жизнь сложнее тех частных случаев, с которыми так замечательно справляются экспериментальные ОС в лаборатории.
Основная проблема современных ОС — высокая стоимость системного вызова. Сингулярити показывает, как ее можно сократить еще примерно на порядок.
Естественно, промышленная ось должна очень-очень много что уметь; но главное принципиально уже доказано — модель работает. Никаких принципиальных причин получить худшие результаты при построении промышленной оси с софтной изоляцией процессов нет.
НС>>Могу. Достаточно верификатор сделать частью ОС, и не надо никого никуда лицензировать. Pzz>Это теоретически неразрешимая задача.
К счастью, на практике она уже разрешена.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Sinclair однажды (26 июня 2008 [Четверг] 06:39) писал в rsdn.flame.comp:
> Pzz>В C#, насколько я помню, есть массивы. Кто проверяет границы? > Код. > В простых случаях JIT устраняет проверки на выход за границы. В сложных — к операции доступа добавляется одна ассемблерная инструкция.
Синклер, глянь в этой ветке на пару сообщений выше.
Цитирую "Сингулярити не использует JIT."
Здравствуйте, Sheridan, Вы писали:
S>Синклер, глянь в этой ветке на пару сообщений выше. S>Цитирую "Сингулярити не использует JIT."
Ты бы вместо того, чтобы к словам цепляться, лучше бы освоился в технических вопросах. А то, честное слово, стыдно за таких безграмотных линуксоидов.
Да, в Сингулярити AOT. Но это несущественно, все отличие, по сути, в том, что он сразу делает трансляцию в нативный код, а не по мере выполнения кода (как JIT).
WFrag однажды (26 июня 2008 [Четверг] 10:02) писал в rsdn.flame.comp:
> Ты бы вместо того, чтобы к словам цепляться, лучше бы освоился в технических вопросах. А то, честное слово, стыдно за таких безграмотных линуксоидов.
Ну должен же тут хоть ктото в недоделанном дотнете не разбираться.
Умников, хающих линух, но не разбирающихся в нем тут дофига.
> Да, в Сингулярити AOT. Но это несущественно, все отличие, по сути, в том, что он сразу делает трансляцию в нативный код, а не по мере выполнения кода (как JIT).
Ура, микрософт изобрел Gentoo Все апплодируют.
WFrag однажды (26 июня 2008 [Четверг] 10:13) писал в rsdn.flame.comp:
> Ага. А теперь покажи мне в твоем Gentoo оптимизацию (инлайн) вызова функции из .so-шки из другого пакета. Поулыбаемся вместе.
Статическая сборка?
Здравствуйте, Sheridan, Вы писали:
S>WFrag однажды (26 июня 2008 [Четверг] 10:13) писал в rsdn.flame.comp:
>> Ага. А теперь покажи мне в твоем Gentoo оптимизацию (инлайн) вызова функции из .so-шки из другого пакета. Поулыбаемся вместе. S>Статическая сборка?
Чёрта-с-два. Не будет инлайна. Будет чуть быстрее, но не более. И удачи тебе в поддержке такой системы.
Здравствуйте, Sheridan, Вы писали: S>Синклер, глянь в этой ветке на пару сообщений выше. S>Цитирую "Сингулярити не использует JIT."
Это не очень важно. Барток построен по примерно тем же принципам. Под джитом в данном случае я имел в виду любой компилятор MSIL->native. Просто некоторые люди тут явно думают, что там бегает супермедленная виртуальная машина, которая интерпретирует код MSIL строчка за строчкой. Типа
if (operation == "ARRAY_ACCESS") then begin
array_operand = array_table.lookup_slow(operand1);
index_operand = calculator_engine.evaluate_slow_scalar(operand2);
if (index_operand == previous_operand) then goto ARRAY_ACCESS_FAST;
if (index_operand.type != "int32") then throw_slow new InvalidArgumentException("Variable i has wrong type!");
if (index_operand.slow_as_int() > array_operand.calc_length_through_iteration())
then throw_slow new ArrayOutOfBoundException("Variable i is to large!");
else if index_operand.slow_as_int() < 0
then throw_slow new ArrayOutOfBoundException("Variable i is to small!");
end
Ну так вот: это неправда.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
WFrag однажды (26 июня 2008 [Четверг] 10:22) писал в rsdn.flame.comp:
>>> Ага. А теперь покажи мне в твоем Gentoo оптимизацию (инлайн) вызова функции из .so-шки из другого пакета. Поулыбаемся вместе. > S>Статическая сборка? > Чёрта-с-два.
Ну тогда объясни подробнее что это делает.
Напоминаю, я админ, не программер.
> Не будет инлайна. Будет чуть быстрее, но не более.
А инлайн прямотаки сверхприрост дает?
> И удачи тебе в поддержке такой системы.
revdep-rebuild
Sinclair однажды (26 июня 2008 [Четверг] 10:23) писал в rsdn.flame.comp:
> Ну так вот: это неправда.
Ну я рад за вас. Серьезно.
Осталось только поверить что дотнет чуть более доделанный, чем я думал.
Здравствуйте, Sheridan, Вы писали: >> Ну так вот: это неправда. S>Ну я рад за вас. Серьезно. S>Осталось только поверить что дотнет чуть более доделанный, чем я думал.
Он намного более доделанный, чем ты думаешь. Впрочем, это не изменить: тебе три года рассказывают про дотнет, ты продолжаешь изобретать бредни.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sheridan, Вы писали:
S>Ну тогда объясни подробнее что это делает. S>Напоминаю, я админ, не программер.
Что именно объяснить?
>> Не будет инлайна. Будет чуть быстрее, но не более. S>А инлайн прямотаки сверхприрост дает?
На моём тупом тесте (вызов функции из другого .c файла в слуаче C и вызов по интерфейсу в случае Java), C выдал 43.3 секунды, Java (после "прогрева", JIT/Hotspot в Java не сразу срабатывает) выдала 5.64 секунды.
>> И удачи тебе в поддержке такой системы. S>revdep-rebuild
Ой не уверен, что он поможет. revdep-rebuild, AFAIK, просто ищет "сломанные" ссылки на символы и пересобирает соответствующие пакеты. Если же перекомпилить какую-то базовую библиотеку статикой, то вроде как ничего и не сломается.
WFrag однажды (26 июня 2008 [Четверг] 11:17) писал в rsdn.flame.comp:
> S>Ну тогда объясни подробнее что это делает. > S>Напоминаю, я админ, не программер. > Что именно объяснить?
Что это за оптимизация такая
>>> Не будет инлайна. Будет чуть быстрее, но не более. > S>А инлайн прямотаки сверхприрост дает? > На моём тупом тесте (вызов функции из другого .c файла в слуаче C и вызов по интерфейсу в случае Java), C выдал 43.3 секунды, Java (после "прогрева", JIT/Hotspot в Java не сразу > срабатывает) выдала 5.64 секунды.
Слушай, ты тесты явы то наверное проводил на коре квадро, а С на 8086?
Иначе никак не могу объяснить такие тормоза. Может с порядком ошибся, и не 43сек, а 0,43?
>>> И удачи тебе в поддержке такой системы. > S>revdep-rebuild > Ой не уверен, что он поможет. revdep-rebuild, AFAIK, просто ищет "сломанные" ссылки на символы и пересобирает соответствующие пакеты. Если же перекомпилить какую-то базовую > библиотеку статикой, то вроде как ничего и не сломается.
Может быть, не проверял.
Во всяком случае static не пользую.
Здравствуйте, Sheridan, Вы писали:
S>WFrag однажды (26 июня 2008 [Четверг] 11:17) писал в rsdn.flame.comp:
>> S>Ну тогда объясни подробнее что это делает. >> S>Напоминаю, я админ, не программер. >> Что именно объяснить? S>Что это за оптимизация такая
Очень простая. На пальцах это примерно так:
Есть функция, компилируем её в .a или в .so:
int func(int a, int b) {
return a+b;
}
В другом файле есть код, её использующий:
int res = 0;
for(int i = 0; i < count; ++i) {
res = func(res, i);
}
Так вот оптимизация заключается в том, что компилятор просто берет и встраивает код функции в цикл, т.е получаем эквивалентный код:
for(int i = 0; i < count; ++i) {
res = res + i;
}
Так вот, ld/ld-linux (статический/динамический линкер) такой финт провернуть не могут (если неправ -- научите как их заставить ). Потому что информации на момент линковки в .so/.a недостаточно.
А самые умные компиляторы ещё и цикл выкинут заменив на выражение (count — 1) * count / 2. Этого Java, похоже, не осилила. Но по косвенным причинам, LLVM это сумел сделать. А LLVM — сюрприз — как раз и основан на концепте байткода
S>Слушай, ты тесты явы то наверное проводил на коре квадро, а С на 8086?
Нет, все на своем ноуте.
S>Иначе никак не могу объяснить такие тормоза. Может с порядком ошибся, и не 43сек, а 0,43?
См. выше. Java просто выкинула вызов функции вообще.
WFrag однажды (26 июня 2008 [Четверг] 11:59) писал в rsdn.flame.comp:
> Есть функция, компилируем её в .a или в .so: >
> int func(int a, int b) {
> return a+b;
> }
>
> > В другом файле есть код, её использующий: > >
> int res = 0;
> for(int i = 0; i < count; ++i) {
> res = func(res, i);
> }
>
> > Так вот оптимизация заключается в том, что компилятор просто берет и встраивает код функции в цикл, т.е получаем эквивалентный код: >
> for(int i = 0; i < count; ++i) {
> res = res + i;
> }
>
Ну и чем это отличается от статической линковки?
> S>Иначе никак не могу объяснить такие тормоза. Может с порядком ошибся, и не 43сек, а 0,43? > См. выше. Java просто выкинула вызов функции вообще.
43сек это бред.
Здравствуйте, Sheridan, Вы писали:
S>Ну и чем это отличается от статической линковки?
При статической линковке у тебя будет вызов функции. При инлайне такого вызова вообще не будет — код функции будет скопирован в цикл.
S>43сек это бред.
На самом деле, просто тест такой искусственный. Стоимость выполнения кода функции крайне мала по сравнению с кодом, который осуществляет её вызов (подготовка аргументов, вызов).
WFrag однажды (26 июня 2008 [Четверг] 12:20) писал в rsdn.flame.comp:
> Здравствуйте, Sheridan, Вы писали: > > S>Ну и чем это отличается от статической линковки? > При статической линковке у тебя будет вызов функции. При инлайне такого вызова вообще не будет — код функции будет скопирован в цикл.
man gcc
-finline-functions
Integrate all simple functions into their callers. The compiler heuristically decides which functions are simple enough to be worth integrating in this way.
If all calls to a given function are integrated, and the function is declared "static", then the function is normally not output as assembler code in its own right.
Enabled at level -O3.
-finline-functions-called-once
Consider all "static" functions called once for inlining into their caller even if they are not marked "inline". If a call to a given function is integrated, then the
function is not output as assembler code in its own right.
Enabled if -funit-at-a-time is enabled.
-fearly-inlining
Inline functions marked by "always_inline" and functions whose body seems smaller than the function call overhead early before doing -fprofile-generate instrumentation
and real inlining pass. Doing so makes profiling significantly cheaper and usually inlining faster on programs having large chains of nested wrapper functions.
А чем тогда это отличается от статической линковке при поддержке?
> S>43сек это бред. > На самом деле, просто тест такой искусственный. Стоимость выполнения кода функции крайне мала по сравнению с кодом, который осуществляет её вызов (подготовка аргументов, вызов).
бред.
Здравствуйте, Sheridan, Вы писали:
>> Здравствуйте, Sheridan, Вы писали: >> >> S>Ну и чем это отличается от статической линковки? >> При статической линковке у тебя будет вызов функции. При инлайне такого вызова вообще не будет — код функции будет скопирован в цикл. S>man gcc S>
S> -finline-functions
S> Integrate all simple functions into their callers. The compiler heuristically decides which functions are simple enough to be worth integrating in this way.
S> If all calls to a given function are integrated, and the function is declared "static", then the function is normally not output as assembler code in its own right.
S> Enabled at level -O3.
S> -finline-functions-called-once
S> Consider all "static" functions called once for inlining into their caller even if they are not marked "inline". If a call to a given function is integrated, then the
S> function is not output as assembler code in its own right.
S> Enabled if -funit-at-a-time is enabled.
S> -fearly-inlining
S> Inline functions marked by "always_inline" and functions whose body seems smaller than the function call overhead early before doing -fprofile-generate instrumentation
S> and real inlining pass. Doing so makes profiling significantly cheaper and usually inlining faster on programs having large chains of nested wrapper functions.
S>
Да. Могу тебя порадовать. Это замечательно работает в пределах _одного_ .c файла. И тогда вкупе с раскруткой циклов C уделывает Java в два-три раза. Результат на моей машине — 1.8 секунды.
S>А чем тогда это отличается от статической линковке при поддержке?
Опять же. Инлайнить умеет gcc, а не ld/ld-linux.so. А статическую линковку делают вторые. Поэтому инлайнинг работает только в пределах одного компилируемого файла. Если ты делаешь вызов однострочной функции из, скажем, libgtk-x11-2.0.so никакой инлайнинг тебе не поможет. Именно поэтому в C++ для того, чтобы какой-то метод класса заинлайнился, его вписывают в заголовочные файлы. Тогда он попадает в каждый компилируемый файл, куда включается этот заголовок и компилятор имеет возможность его заинлайнить.
>> S>43сек это бред. >> На самом деле, просто тест такой искусственный. Стоимость выполнения кода функции крайне мала по сравнению с кодом, который осуществляет её вызов (подготовка аргументов, вызов). S>бред.
WFrag однажды (26 июня 2008 [Четверг] 12:33) писал в rsdn.flame.comp:
> Да. Могу тебя порадовать. Это замечательно работает в пределах _одного_ .c файла.
Помоему инлайнинг внешних функций противоречит самой концепции С/С++, хотя не уверен
Да и с дальнейшей поддержкой тяжко будет.
> И тогда вкупе с раскруткой циклов
gcc умеет не только циклы оптимизировать.
в общем случае есть даже стандартные наборы оптимизаций:
-O
-O1 Optimize. Optimizing compilation takes somewhat more time, and a lot more memory for a large function.
With -O, the compiler tries to reduce code size and execution time, without performing any optimizations that take a great deal of compilation time.
-O turns on the following optimization flags: -fdefer-pop -fdelayed-branch -fguess-branch-probability -fcprop-registers -floop-optimize -fif-conversion -fif-conversion2
-ftree-ccp -ftree-dce -ftree-dominator-opts -ftree-dse -ftree-ter -ftree-lrs -ftree-sra -ftree-copyrename -ftree-fre -ftree-ch -funit-at-a-time -fmerge-constants
-O also turns on -fomit-frame-pointer on machines where doing so does not interfere with debugging.
-O doesn’t turn on -ftree-sra for the Ada compiler. This option must be explicitly specified on the command line to be enabled for the Ada compiler.
-O2 Optimize even more. GCC performs nearly all supported optimizations that do not involve a space-speed tradeoff. The compiler does not perform loop unrolling or function
inlining when you specify -O2. As compared to -O, this option increases both compilation time and the performance of the generated code.
-O2 turns on all optimization flags specified by -O. It also turns on the following optimization flags: -fthread-jumps -fcrossjumping -foptimize-sibling-calls -fcse-fol‐
low-jumps -fcse-skip-blocks -fgcse -fgcse-lm -fexpensive-optimizations -fstrength-reduce -frerun-cse-after-loop -frerun-loop-opt -fcaller-saves -fpeephole2 -fsched‐
ule-insns -fschedule-insns2 -fsched-interblock -fsched-spec -fregmove -fstrict-aliasing -fdelete-null-pointer-checks -freorder-blocks -freorder-functions -falign-func‐
tions -falign-jumps -falign-loops -falign-labels -ftree-vrp -ftree-pre
Please note the warning under -fgcse about invoking -O2 on programs that use computed gotos.
-O3 Optimize yet more. -O3 turns on all optimizations specified by -O2 and also turns on the -finline-functions, -funswitch-loops and -fgcse-after-reload options.
-O0 Do not optimize. This is the default.
-Os Optimize for size. -Os enables all -O2 optimizations that do not typically increase code size. It also performs further optimizations designed to reduce code size.
-Os disables the following optimization flags: -falign-functions -falign-jumps -falign-loops -falign-labels -freorder-blocks -freorder-blocks-and-partition
-fprefetch-loop-arrays -ftree-vect-loop-version
If you use multiple -O options, with or without level numbers, the last such option is the one that is effective.
Options of the form -fflag specify machine-independent flags. Most flags have both positive and negative forms; the negative form of -ffoo would be -fno-foo. In the table
below, only one of the forms is listed---the one you typically will use. You can figure out the other form by either removing no- or adding it.
The following options control specific optimizations. They are either activated by -O options or are related to ones that are. You can use the following flags in the rare
cases when "fine-tuning" of optimizations to be performed is desired.
> > S>А чем тогда это отличается от статической линковке при поддержке? > Опять же. Инлайнить умеет gcc, а не ld/ld-linux.so. А статическую линковку делают вторые. Поэтому инлайнинг работает только в пределах одного компилируемого файла. Если ты > делаешь вызов однострочной функции из, скажем, libgtk-x11-2.0.so никакой инлайнинг тебе не поможет. Именно поэтому в C++ для того, чтобы какой-то метод класса заинлайнился, его > вписывают в заголовочные файлы. Тогда он попадает в каждый компилируемый файл, куда включается этот заголовок и компилятор имеет возможность его заинлайнить.
Тоесть "давай наперегонки, только я на велосипеде, а ты на карачках"?
Я правильно понял, что С код специально ограничивали от инлайнинга?
> Можешь сам проверить. Могу дать исходники теста.
Давай.