WebAssembly - первые тесты
От: alex_public  
Дата: 20.03.17 01:06
Оценка: 9 (7) :)
Сразу парочка небольших предупреждений, для редких любителей придираться к формулировкам:
1. Тесты эти очевидно не первые в глобальном смысле — подобного полно в инете. Они первые для меня, в том смысле, что я решил пощупать новинку руками и потом поделиться впечатлениями на форуме.
2. Это не реальное глобальное тестирование платформы, а мой маленький тест, проверяющий быстродействие языка в одной узкой (интересной мне) области, так что на лавры SPEC или даже хотя бы 7z он не претендует ни малейшей степени. Хотя определённые выводы по эффективности работы с памятью, оптимизации циклов и т.п. по нему можно сделать.
Если после этих предупреждений вам ещё интересно, то продолжим. )

У меня давным давно имеется набор тестов, проверяющих быстродействие на некоторых интересных мне сценариях. Изначально там были только нужные мне языки, а потом ради фана добавилось ещё несколько. Результаты парочки этих тестов я даже публиковал на этом форуме. Соответственно после новости о по сути релизе WebAssembly у меня появилось огромное желание пощупать эту технологию руками, в том числе и на этих тестах. И хотя у меня сейчас почти нет свободного времени из-за важного проекта в совсем другой области, я всё же не удержался и потратил его на это. )))

Изначально все тесты были естественно консольными (JS через node.js), но раз тут зашла речь о бразуерах, а то я решил чуть изменить привычный уклад. Начал я с того, что переделал JS тест под браузер, добавив при этом визуализацию через WebGL (всего несколько строчек и за процессом стало интересно наблюдать).

После этого я взялся за WebAssembly, причём решил разобраться на самом низком уровне, без всякого Emscripten, генерирующего кучу всякой сомнительной js "обвязки" — чистый LLVM. Сам код теста очевидно был скопирован из C++ варианта, но встал вопрос вывода информации (интеграции с браузером) — как раз то, что тут недавно активно обсуждалось на форуме. Так вот ситуация там следующая: из коробки нет никакой интеграции вообще, но при этом есть все возможности для построения любого уровня интеграции (правда пока работающего только с быстродействием js, но для "системных" вызовов сойдёт). Выглядит это так: при загрузке wasm модуля (пока это делается через js, хотя в будущем обещают делать это через html тег script) ему просто передаётся табличка (json) соответствия между именами импортируемых модулем функций и реальными js (или прямо DOM, не суть) функциями. Т.е. понятно, что можно элементарно построить любую интеграцию (причём сделав это один раз для всех проектов и дальше таскать это один js файл везде), работающую не хуже текущего JS расклада. Однако лично мне для теста было делать это лень даже для тех нескольких используемых мной webgl функций, так что я решил проблему совсем "нехорошо", но зато быстро и просто — я завёл ровно одну импортируемую функцию по имени RunJS, которая отображалась на функцию eval из JS. Естественно в реальном проекте так делать нельзя, но в данном тесте можно, т.к. на замеряемом участке кода нет никаких внешних вызовов. Ну и да, по интеграции памяти (о чём тут многие переживали) как раз никаких проблем нет — линейная память wasm просто доступна из js под видом массива. В общем в итоге для вывода информации wasm пример использовал просто скопированные куски кода из js примера. )))

Это уже почти конец истории) Единственно что я ещё решил ради интереса приделать визуализацию и к C++ тесту, чтобы оценить визуально максимальное быстродействие (fps под 500 — это конечно за пределами, для C++ явно надо брать 4K разрешение). И для этого опять же оказалось достаточно скопировать тот же самый код отрисовки из JS примера (только с простейшей трансформацией вида gl.viewport => glViewport) — всё же хорошо что в браузере взяли для 3Д графики не какое-то своё оригинальное извращение, а классику.

Ну и напоследок мне пришла в голову мысль протестировать результат работы Emscripten на полученном C++ тесте, получив тем самом asm.js реализацию. Компиляция прошла вообще без вопросов и пример с ходу заработал (т.е. имеем абсолютно одинаковый исходник и в роли нативного приложения винды и работающее в браузере). Более того, Emscripten умеет генерировать и wasm, но пока (в будущем это планируют изменить на тот метод, которым я пользовался) стандартным путём для его генерации является промежуточный asm.js (а не llvm, как у меня), так что и производительность закономерно получилась другая.

Ну а остальные языки остались жить в консоли — только прогнал тест в очередной раз для них. )))

И так результаты в отсортированном порядке (значение — это усреднённое время исполнения одной итерации):
Язык t, мс
JS 15,6
C# 15,1
ASM.JS 12,5
WASM из ASM.JS 11,4
Java 10,1
C# unsafe 8,9
WASM 8,6
D 7,2
C++ nosimd 4,4
C++ 1,9
Увидив эти результаты я в начале слегка расстроился — быстродействие wasm оказалось всего в 2 раза лучше JS и в 4 раза хуже C++, хотя по изначальным предпосылкам (LLVM база) должно было быть намного лучше. Однако глянув в генерируемых код, а потом уже с осознанием в соответствующий раздел документации wasm, я легко увидел причину — там тупо не работает SIMD. Если же сравнивать результат с "C++ nosimd", то разница выглядит более адекватно. И эта разница очевидно обусловлена работой песочницы. Можно даже оценить какой результат будет выдавать WASM, когда ему подключат поддержку SIMD (это у них стоит в приоритетных целях: http://webassembly.org/docs/future-features/). В целом можно сказать, что ситуация с быстродействием удовлетворительная, но до реализации SIMD говорить о "быстродействие C++ в браузере" рановато — пока для таких целей проще использовать тот же ASM.JS.

Кстати, небольшое отдельное замечание не по теме: производительность основных участников за несколько последних лет не особо изменилась, кроме одного — JS показал существенный рост по сравнению со старыми тестам, уже практически догнав статические ненативные языки. Но это к теме разговора не относится, просто замечание.

Основные выводы. Вот прямо сейчас смысла от применения wasm не особо много, но при этом сама технология отлично продуманная и перспективная. После добавления поддержки SIMD и многопоточности (их первые планы после релиза) она уже отлично подойдёт для реализации различных тяжёлых вычислений в браузере (различные кодеки, расчёт моделей и сцен, криптография и т.п.), подразумевая при этом сам сайт по прежнему на JS. После подключения доступа к DOM (тоже есть в планах, но позже, причём речь о доступе не в стиле JS, а о эффективном нативном) сразу же появится смысл избавится от JS целиком, но это опять же только на таких специфических сайтах (по сути онлайн-приложениях). Ну а после портирования на эту платформу (это наверняка произойдёт, если уж есть доступ у C/C++ кода, на которых все эти языки и написаны) множества современных скриптовых языков наверняка появится смысл и в использование wasm на обычных сайтиках (в роли уже собранного движка любимого скриптового языка, распространяемого как готовый модуль).

P.S. Выложил пару исходников прямо в файлы на форуме (кстати забавно, что сайт ругнулся "формат файлов ".wasm" не поддерживается" — заменил на какое-то другое случайное (букву z) и загрузил нормально — наркомания какая-то на сайте), чтобы не было никаких сомнений в реальности теста: JS Test и WASM Test. Работа запускается/приостанавливается по щелчку мышки на отображаемой области.
P.P.S. Тестировал всё это только в современном Firefox, так что в остальных браузерах может и не работать что-то — не знаю, не проверял, т.к. для тестов это не актуально. )
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.