Size: a a a

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

2021 October 26

M

MaxGraey in WebAssembly — русскоговорящее сообщество
По моему проще компрессию специфичную для wasm сделать. А кстати чем brotli не угодил?
источник

Б

Богдан in WebAssembly — русскоговорящее сообщество
Так если посмотреть как мы сможем оптимизировать эту компрессию то рано или поздно мы придем к этому client-side компилятору. То есть сначала мы используем gzip или brotli, потом мы можем написать свой специфический для wasm-модулей архиватор который будет в курсе про специфику wasm-формата а потом для этого архиватора можно добавить специфические инструкции которые будут модифицировать wasm-модуль - например инлайнить функции или дублировать код для дженериков (и это скорее всего окажется эффективней чем пост-фактум распознавать дублирование в потоке байтов как это делают обычные архиваторы)
источник

К

Константин in WebAssembly — русскоговорящее сообщество
Нет, пока нельзя эмитить в память
источник

К

Константин in WebAssembly — русскоговорящее сообщество
Или пока не будет нормальных wasm-modules
источник

К

Константин in WebAssembly — русскоговорящее сообщество
Можно ща взять любой компилятор, вогнать в WASM, линкануть с IR/байткодом и передать на клиент, и им сэмитить WASM модуль.
Но это будет кастыльно медлено и весить овердохрена.
Тебе придется компилировать компилятор, который будет компилировать бинарь, и его еще потом компилировать.
источник

M

MaxGraey in WebAssembly — русскоговорящее сообщество
wasm уже был создан так, что бы занимать как можно меньше места, именно поэтому он использует LEB128 где только можно, использует стековую структоризацию, поддержывает несколько вариантов выхода из CFG, а так же все CFG инструкции поддерживают опциональный возвращаемый тип и т д. Можно придумать более эффективный с точки зрения выполнения байткод, но с точки зрения компактности - это вряд ли. Кроме того, нужно учитывать оверхед на сам код для подобного встроенного компилятора
источник

AC

Alexander Chichigin in WebAssembly — русскоговорящее сообщество
Flash и Java Applets покоя не дают? 😉

Вы же в курсе, что браузеры и так компилируют Wasm модули в нативный код с инлайнингом и прочими оптимизациями? 😊
источник

M

MaxGraey in WebAssembly — русскоговорящее сообщество
Ну такая схема сделает невозможным стриминговую компиляцию. то есть по-существу вы во много раз замедлите инициализацию такого модуля
источник

M

MaxGraey in WebAssembly — русскоговорящее сообщество
Просто не нужно использовать Blazor =)
источник

SR

Sergey Rubanov in WebAssembly — русскоговорящее сообщество
🙂
источник

Б

Богдан in WebAssembly — русскоговорящее сообщество
Это понятно но я говорил про компиляторные оптимизации которые раздувают размер бинарника. Например инлайнить нерекурсивные функции или нет. Сможет ли brotli распознать все эти места с дублированием функций в потоке байт после того когда мы заинлайним все функции в wasm-модуле? Я что-то сомневаюсь не говоря уже про более сложные кейсы generic-функций когда дублируется тело функции но с небольшими изменениями
источник

M

MaxGraey in WebAssembly — русскоговорящее сообщество
Просто для справки, скомпилированный в wasm JavaScriptCore весит меньше чем hello world на Blazor =)
источник

M

MaxGraey in WebAssembly — русскоговорящее сообщество
> Это понятно но я говорил про компиляторные оптимизации которые раздувают размер бинарника

Компилируй с Oz в чем проблема?=)
источник

M

MaxGraey in WebAssembly — русскоговорящее сообщество
В некоторых компиляторах есть такая штука как outlining. В LLVM тоже экспериментировали с этим:
https://www.youtube.com/watch?v=yorld-WSOeU
источник

M

MaxGraey in WebAssembly — русскоговорящее сообщество
Но еще раз Brotli должен отлично схватывать такие кейсы, так что не знаю насколько все это стоит делать
источник

M

MaxGraey in WebAssembly — русскоговорящее сообщество
В LLVM кстати это есть с 2016го
https://llvm.org/doxygen/MachineOutliner_8cpp_source.html
источник

M

MaxGraey in WebAssembly — русскоговорящее сообщество
Насчет специализированного компрессора для Wasm. Вот прототип:
https://github.com/WebAssembly/decompressor-prototype

Но оказалось это не нужно. Brotli вполне неплохо справляется и без этого
источник

Б

Богдан in WebAssembly — русскоговорящее сообщество
Когда мы поставляем пользователю тот самый бинарник который будет выполнятся нам приходится выбирать между скоростью (например полиморфные проверки в дженерик-функциях вместо прямого вызова/чтения в случае дублирования)  и размером бинарника который будет передаваться по сети (разница между 100кб и 10мб будет ощущаться очень сильно).
А вот если будем поставлять промежуточный формат с включенным компилятором  то уже появляется огромное пространство для экспериментов. Понятное дело что сам компилятор может весить дохрена и нивелировать выигрыш в размере но что если мы вместе с wasm-модулем (или точнее некого промежуточного представления) еще будем генерировать специфичный для этого модуля компактный компилятор  (который только распакует, продублирует и поменяет что надо и сгенерирует уже конечный wasm-модуль для выполнения)
источник

M

MaxGraey in WebAssembly — русскоговорящее сообщество
Вот почему у Blazor у которого дженерики не мономорфизируются выходит 5-6 мб на hello world, а такая же программа на Rust у которого они мономорфизируется в несколько килобайт? =)
источник

Б

Богдан in WebAssembly — русскоговорящее сообщество
Этого я не знаю, самому интересно, но сама идея мне кажется классной потому что позволяет решить этот трейд-офф и усидеть на двух стульях :)
Я конечно понимаю что мы не полностью решаем эту диллему так как большой wasm-модуль будет также медленно компилироваться но думаю в большинстве случаев все равно время первого запуска будет быстрее потому что выигрываем во времени передачи по сети. Например при скорости 100кб/c передача оптимизированного по скорости (а не по размеру) wasm-бинарника размером 1мб будет занимать 10 секунд и дальше благодаря instantiateStreaming получаем общее время запуска те же 10 секунд.
А если будем передавать некий промежуточный компактный байт-код то даже жертвуя instantiateStreaming и тратя пару секунд на собственную пост-обработку-компиляцию мы все равно выигрываем если размер этого промежуточного представления будет в два раза меньше (0.5мб -> 5сек + 2-3 сек на компиляцию < 10cек) и при этом не жертвуем производительностью
источник