Size: a a a

WebAssembly — русскоговорящее сообщество

2021 October 08

でゲソ in WebAssembly — русскоговорящее сообщество
это будет году к 30
источник

DM

Demi Murych in WebAssembly — русскоговорящее сообщество
и ты абсолютно прав. и об этом тыщу раз говорилось господам из v8.  
но им понадобилось 5 лет чтобы понять, что концепция риал-ворлд -перформанс,  без обоснования является пшиком.
Ответом на это была сначала попытка запустить v8-light, и в конце релиз spurkplug - non optimizing javascript compiller. Который внезапно показал в их же тестах от 5 до 20% прироста производительности в зависимости о реплики.

Просто вдумайтесь, компилятор где отключили почти все типы отптимизаций, внезапно дал прирост производительности.

Версия v8 9.1 в хроме 91 версия, включить и попробовать можно флагом --sparkplug
источник

N

Nikolay in WebAssembly — русскоговорящее сообщество
да, где-то такое уже пробегало, на ровне с тем, что отключение каких-то фич, еще и повышает безопасность, не снижая производительности или снижая несущественно
источник

M

MaxGraey in WebAssembly — русскоговорящее сообщество
Это про jitless. И это немного другое
источник

M

MaxGraey in WebAssembly — русскоговорящее сообщество
Там имелось ввиду общая скорость (скорость компиляции + скорость выполнения). И она возросла да, но за счет того то произошла перебалансировка - скорость компиляции существенно возросла, при том то скорость выполнения упала, хотя не на столько что бы суммарная скорость просела бы
источник

DI

Dmitry Ilyin in WebAssembly — русскоговорящее сообщество
вдруг кому будет актуально
https://www.piter.com/collection/soon/product/webassembly-v-deystvii
источник

DM

Dmitry M in WebAssembly — русскоговорящее сообщество
Открываешь книгу по WebAssembly, а там C++. Вот так поворот!
источник

M

MaxGraey in WebAssembly — русскоговорящее сообщество
Это книга из будущего?)
источник

DI

Dmitry Ilyin in WebAssembly — русскоговорящее сообщество
все рос издатели так делают)
источник

PM

Pavel Mellonges® in WebAssembly — русскоговорящее сообщество
Все равно устарела уже
источник
2021 October 09

Б

Богдан in WebAssembly — русскоговорящее сообщество
Народ, я тут пытаюсь понять как компилятор должен вычислить оффсет для полей литеральных объектов (структурная типизация) - когда мы в функции объявляем что принимаем объект с таким то полем
const someFunc = (obj: { a: number }) => {
   obj.a += 1;
};
но передавать мы можем объекты где помимо этого поля могут быть разнообразные сочетания других полей
someFunc({a: 1, b: 1})
someFunc({x: 1, a: 1, z: 1})
И я вспомнил что эта проблема похожа на проблему множественного наследования и появился вопрос - кто-нибудь знает как с++ компиляторы понимают по какому оффсету расположено поле с таким-то именем в случае множественного наследования?
Представим себе 26 базовых классов каждый из который объявляет одно поле
class A {
 int a;
}
class B {
 int b;
}
...//еще 22 класса
class Y {
 int y;
}
class Z {
 int z
}
И есть функция которая объявляет что в качестве параметра принимает объекты с полем "k"
void someFunc(K& obj){
 obj.k += 1;
}
То есть к этой функции можно передавать объекты классов которые наследуются от класса K
Но дальше с множественным наследованием мы можем создать и передать функции объекты с различными сочетаниями других полей, например
 
class KAB: K, A, B {} //{k: 0, a: 0, b: 0}
class KAO: K, A, T {} //{k: 0, a: 0, t: 0}
class KNJ: K, A, T {} //{k: 0, n: 0, j: 0}
//много других сочетаний
someFunc(new KAB())
someFunc(new KAO())
someFunc(new KNJ())
Тут можно заметить что поле "к" находится по первому оффсету, а если нет то мы отсортируем в общем сделаем так чтобы оффсеты полей которые принимает функция будут находиться в начале объекта. Ок, это будет работать в случае если у нас есть только одна такая функция, но что если функций много и каждой нужно знать оффсет  поля со своим именем или даже несколько таких полей. Тут уже не получится сделать так чтобы все поля с таким именем лежали по одинаковым оффсетам потому что сочетания полей (базовых класов) могут быть самые разные
void someFunc(K& obj){
 obj.k += 1;
}
void someFunc2(T& obj){
 obj.k += 1;
}
auto obj = new KOT();
someFunc(obj)
someFunc2(obj)

auto obj = new AKT();
someFunc(obj)
someFunc2(obj)
Поверхностное гугление не дало ответов на вопросы как компилятор с++ вычисляет оффсеты для таких различных сочетаний базовых классов. Есть пейпер от Страуструпа https://www.usenix.org/legacy/publications/compsystems/1989/fall_stroustrup.pdf но там ничего не написано про такие сочетания, есть общие фразы вроде ": the compiler knows the location in the object of each
member and generates the appropriate code" или для вызова методов которые обращаются к this "This constant, detta(B), is the relative position of the B part of c. This delta is
known to the compiler that transforms the call", но каким образом компилятор знает оффсеты если сочетания базовых классов могут быть самыми разнообразными непонятно.  Если отсортировать поля то все равно будут разные оффсеты из-за того что не все поля присутствуют в объекте. Единственный вариант сделать чтобы поля имели одинаковые оффсеты это сделать убер-объект большого размера который будет включать каждое поле даже если оно не нужно но смысла в этом нет так как это будут бессмысленные затраты по памяти.
В общем я тут придумал схему как можно вычислить оффсеты (храним в хедере объекта битмап наличия полей и вычисляем оффсет через количество предыдущих установленных бит popcnt инструкцией) но хотелось бы узнать как с++ компиляторы решают эту проблему (может я пропустил что-то очевидное)
источник

AC

Alexander Chichigin in WebAssembly — русскоговорящее сообщество
Во-первых, структурное подтипирование не имеет ничего общего с множественным наследованием.

Во-вторых, как обычно реализуют множественное наследование компиляторы C++ написано в Design and Evolution. TL;DR: компилятор просто кладёт рядом данные и vtable, соответствующие каждому из предков, поскольку функция принимает указатель и ожидает там увидеть данные и vtable по одним и тем же смещениям для каждого конкретного класса — просто передаём ей указатель на нужный кусок (заголовка) объекта.

В-третьих для структурной типизации и подтипирования нужно делать "честный" доступ по имени (хеш-таблицу как в JS/Python/whatever). Вероятно, в случае статической структурной типизации (особенно с immutable data) можно вставлять неявные функции преобразования между форматами, в редких случаях когда они не совпали после сортировки полей.
источник

SK

Slava Kuzmich in WebAssembly — русскоговорящее сообщество
Если мир закрытый, можно пронумеровать все классы, и все символы полей. Для каждого символа поля в таблице индексов будет смещение, такое что по индексу fieldSymbolOffset + classId будет лежать индекс поля в классе. Таблица такая в общем случае будет разряженная, ее можно сжимать.
источник

Б

Богдан in WebAssembly — русскоговорящее сообщество
А почему это структурное подтипирование не имеет ничего общего с множественным наследованием? Я вижу полную эквивалентность. Представим что при написании программы на js мы передаем от функции к функции объекты-литералы самых разных шейпов
{a, b}
{a, b, c}
{b, c, d}
{a, x, y}
{b, someField}
{someField, someField2}
Все эти литералы можно представить как класс который наследует от некоторого количества базовых классов (н-классов по одному для каждого уникального поля)
class Base1 { a } 
class Base2 { b }
class Base3 { c }
class Base4 { d }
class Base5 { x }
class Base6 { y }
class Base7 { someField }
class Base8 { someField2 }
и тогда любой литеральный объект можно представить как наследование нескольких базовых классов
const obj = {a, x, y} -> new class extends Base1, Base5, Base6
const obj2 = {b, someField} -> new class extends Base2, Base7
и тогда задача вычисления оффсета поля для объекта который имеет такой-то интерфейс (имеет поле c таким то именем)
function someFunction(obj: {someField}) {
obj.someField += 1;
}
someFunction({b, someField})
someFunction({someField, someField2, a})
someFunction({a, someField2, b, c})
сводится к проблеме вычисления оффсетов при множественном наследовании
function someFunction(obj: Base7) { 
obj.someField += 1;
}
someFunction(new class extends Base2, Base7)
someFunction(new class extends Base7, Base, Base1)
someFunction(new class extends Base1, Base7, Base2, Base3)
и я вот хочу понять как в c++ компилятор понимает по какому оффсету нужно загрузить поле внутри функции которая принимает некий базовый класс а передаем мы объекты классов которые наследуются от нескольких базовых классов (может образоваться комбинаторное количество сочетаний базовых классов)
источник

Б

Богдан in WebAssembly — русскоговорящее сообщество
принимает указатель и ожидает там увидеть данные и vtable по одним и тем же смещениям для каждого конкретного класса — просто передаём ей указатель на нужный кусок (заголовка) объекта

вот мне это и непонятно - как можно передать оффсет на нужный кусок объекта если для разных сочетаний базовый классов поле с таким именем будет иметь разные оффсеты
источник

К

Константин in WebAssembly — русскоговорящее сообщество
при наследовании это же невозможно.
поля будут иметь оффсеты строго по иерархии наследования.

Структурная типизация имеет возможность перетасовать поля, по этому там и нужно иметь доступ по ключу.

так как {а, б} и  {б ,а} одно и тоже только семантически
источник

AC

Alexander Chichigin in WebAssembly — русскоговорящее сообщество
Вы видите полную эквивалентность, потому что смотрите с высоты птичьего полёта. Структурная типизация -- это структурная типизация, а множественное наследование в C++ -- номинальная типизация. Общего -- только слово "типизация". 😄
источник

AC

Alexander Chichigin in WebAssembly — русскоговорящее сообщество
Вы же сами только что написали. Какая проблема, что смещения разные, если компилятор их все знает, потому что сам их и высчитал? Передвигает указатель на нужное смещение и передаёт.
источник

Б

Богдан in WebAssembly — русскоговорящее сообщество
так я и пытаюсь разобраться) Может есть какие-то статьи/доклады с разбором темы укладки полей и вычисления оффсетов при множественном наследовании и структурной типизации? Буду благодарен за ссылки
источник

AC

Alexander Chichigin in WebAssembly — русскоговорящее сообщество
Я уже писал, что я это читал в Design and Evolution. У меня был русский перевод.
источник