Четверг, 21.11.2024, 09:47
WebAssembly
Главная | Блог | Регистрация | Вход
Меню сайта
Наш опрос
Оцените мой сайт
Всего ответов: 0
Мини-чат
Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0

00:48
Четыре попытки асинхронизировать WebAssembly

На многие устройства портировали NetBSD и программы для неё. На цифровом телефоне GrandStream GXV-3140 попадался портированный Pidgin. На ТВ-приставках с Venus Linux и роутерах с OpenWrt портировали много программ. WebAssembly похож на встраиваемые устройства, и всё же он остался непокорённый.

Корни JavaScript

Исходный текст для обычных устройств отличается от того, что требуется для WebAssembly. Когда WebAssembly работает в браузере, он подвержен всё тем же ограничениям, что и программы для браузера. Необходимо постоянно возвращать управление наружу.

Проблема двухцветности

В мире JavaScript происходила эволюция: CPS, deferred, promise, async/await. И пользоваться этим по-прежнему неудобно. async/await порождает проблему двухцветности: нужно отслеживать, какие функции могут быть асинхронные, и либо асинхронность разрастается, перекрашивает всё в свой цвет, либо асинхронность упирается в барьер синхронного интерфейса. Тяжело обращаться с двумя цветами. Также с точки зрения разных цветов есть отличия даже в стандартных классах. Например, у массива Array есть метод forEach, но он сам синхронный, и он ожидает на вход синхронную функцию. Стандартного асинхронного аналога нет. Под аналогом следует понимать метод массива, который вызовет обработку каждого элемента, дожидаясь обработки прошлого.

Странный параллельный запуск

Можно пойти другим путём. Можно запустить обработку элементов параллельно, а потом дожидаться результатов. Такого готового асинхронного метода тоже нет, а наивная попытка написать вскрывает ещё странные особенности асинхронных функций. Вызовы асинхронных функций интуитивно воспринимаются как запуск в другом потоке, но на самом деле они могут выполнить множество операций перед тем, как заснуть и вернуть обещание.

Специфика WebAssembly

В-принципе, можно пытаться повторять тот же путь, что и в JavaScript, и дойти до async/await и всех проблем с ними. Но посмотрим, что пробовали ещё.

Интерпретатор

Очень популярное решение в подобных ситуациях: заменять асинхронный участок кода интерпретируемым. В EmScripten это называлось Emterpreter. Недостаток: замедление в 10 раз и большие проблемы с двухцветностью. Сейчас эта возможность устаревшая.

WARNING: The Emterpreter was removed in emscripten 1.39.17. For details, see the changelog.

Asyncify

Другой попыткой в EmScripten был режим asyncify. Во всех возможных точках останова делались дубликаты функций, в которые можно и продолжить с этой точки. Это, по идее, должно быть максимально быстро, но это приводило к чрезмерному разрастанию кода, который можно продолжить со всех возможных точек останова. Эту возможность объявили устаревшей ещё раньше, чем Emterpreter.

ASYNCIFY has a bad worst-case of large code size: If it needs to modify many methods, it can grow code size very significantly (even 10x more was seen).

Типизированные продолжения

В 2020м было добавлено предложение добавить в WebAssembly типизированные продолжения. Пока не принято, то есть, в браузерах не доступно и, может быть, не будет доступно.

JavaScript Promise Integration (JSPI)

Другой попыткой было сохранение стека WebAssembly за кулисами при попытке взаимодействовать с асинхронным кодом JavaScript. Это было реализовано в одном из браузеров, но требует включения экспериментальных возможностей. Возможно, это так и не будет принято. Также при использовании этой возможности наложены довольно жёсткие ограничения на размер стека, который может быть сохранён на будущее.

Ещё одна попытка

Последнее слово ещё не сказано. Автор видит перспективным идти не по пути CPS и его вариаций вплоть до async/await, а по пути батутизации (trampolined style). Разница: в CPS вызов преобразуется в вызов, и возврат тоже преобразуется в вызов. При батутизации вызов превращается в возврат, и возврат тоже воплощён через возврат. Для исполнения батутизированного кода нужен рантайм, нужен батут, но вот эта комбинация из батута и батут-преобразованного кода и является, по мнению автора, лучшим решением. Автор ставит цель написать транслятор языка Си в WebAssembly с батут-преобразованием. В отличие от Asyncify, оно 1:1, и размер кода не раздувается. Батут похож на интерпретатор, но не замедлен в 10 раз. Ожидаемое замедление в 3 раза, но в обмен на это свобода писать в удобном синхронном стиле и не решать проблемы двухцветности. Такой транслятор должен быть наиболее похож на трансляторы для обычных платформ. Из одних исходников должно быть возможно компилировать для обычных платформ обычными трансляторами, и этим новым транслятором для WebAssembly, по возможности, без необходимости подстраиваться под особенности браузера.

Просмотров: 169 | Добавил: OCTAGRAM | Теги: GreenThreads, coroutine, CPS, WebAssembly, trampolined | Рейтинг: 0.0/0
Всего комментариев: 0
avatar
Вход на сайт
Поиск
Поделиться
Календарь
«  Апрель 2024  »
ПнВтСрЧтПтСбВс
1234567
891011121314
15161718192021
22232425262728
2930
Архив записей
Файлы
[15.07.2024][Документация]
C Intermediate Language: учебник и руководство (0)
[28.05.2024][Философия IT]
Джоэл Спольски о программировании (0)
[25.03.2024][История IT]
Hard drive: Bill Gates and the making of the Microsoft empire (0)
Полезные ссылки