Какое-то дежа вю немного. Миллион лет до нашей эры, Наири, Аналитик и оптимизация численных операций в интерпретаторе. Я думал что все эти проблемы решены и забыты с момента появления сопроцессоров с плавающей. А оно вон как.
Я бы сказал, что интереснее всего разыменование с игнорированием некоторых битов указателя по маске. ARM64, кажется, такое умеет (8 upper bits).
Разгонять сложение двух таггированных вещей - это экономия на спичках для интерпретаторов, а по хорошему все горячее должно быть заjitовано и там такая ситуация должна быть редко --- ядра вычислений-то чаще всего оперируют со значениями в этих ядрах и вычисленными, как следствие их тип jitу заранее известен.
Можете пояснить, что имеется ввиду под упрощением?
Я могу представить ситуации, где они разгоняют GC за счет того, что GC (или скажем read/write barrier) не всегда надо разыменовывать указатель для доступа к дескриптору типа и выяснения на какой объект тот указывает. Но ускорение не означает упрощение :-)
Плюс инструкция, которую thesz описывает слабо GC поможет скорее всего --- во-первых, тут все в память упрется в большинстве случаев, а, во-вторых, код будет скорее всего выглядеть как-то так:
type = type_of_ptr(ptr); switch (type) { // ... }
и цена маскирования будет амортизирована по числу тэгов. В вырожденном случае с одним тэгом (как допустим в V8 и Dart VM) код вообще выглядит вот так:
if (ptr & 0x1) { /* pointer to object */ } else { /* nothing to do, it's a number */ }
Конкретно сравнение с предварительным маскированием непонятно как может помочь окамлу. При вычислениях он уже заранее знает, где есть тэги, а где нет, ибо статически типизирован. Сравнение двух чисел с тэгами делается той же одной операцией, что и чисел без тэгов.
Comments 29
Я думал что все эти проблемы решены и забыты с момента появления сопроцессоров с плавающей. А оно вон как.
Reply
Reply
Разгонять сложение двух таггированных вещей - это экономия на спичках для интерпретаторов, а по хорошему все горячее должно быть заjitовано и там такая ситуация должна быть редко --- ядра вычислений-то чаще всего оперируют со значениями в этих ядрах и вычисленными, как следствие их тип jitу заранее известен.
Reply
Reply
Я могу представить ситуации, где они разгоняют GC за счет того, что GC (или скажем read/write barrier) не всегда надо разыменовывать указатель для доступа к дескриптору типа и выяснения на какой объект тот указывает. Но ускорение не означает упрощение :-)
Плюс инструкция, которую thesz описывает слабо GC поможет скорее всего --- во-первых, тут все в память упрется в большинстве случаев, а, во-вторых, код будет скорее всего выглядеть как-то так:
type = type_of_ptr(ptr);
switch (type) {
// ...
}
и цена маскирования будет амортизирована по числу тэгов. В вырожденном случае с одним тэгом (как допустим в V8 и Dart VM) код вообще выглядит вот так:
if (ptr & 0x1) { /* pointer to object */ } else { /* nothing to do, it's a number */ }
и тут как ни крути и так одна инструкция.
Reply
Reply
При вычислениях он уже заранее знает, где есть тэги, а где нет, ибо статически типизирован.
Сравнение двух чисел с тэгами делается той же одной операцией, что и чисел без тэгов.
Reply
Leave a comment