Показать сообщение отдельно
  #1 (permalink)  
Старый 26.07.2022, 01:01
Аватар для Alikberov
Кандидат Javascript-наук
Отправить личное сообщение для Alikberov Посмотреть профиль Найти все сообщения от Alikberov
 
Регистрация: 16.08.2018
Сообщений: 112

WebAssembly & Сложности SIMD-арифметики
Кaк некогда работающий непосредственно с низким уровнем (Си/Ассемблер) и знакомый с технологией SIMD, попытался я средствами JavaScript реализовать некоторые из инструкций прямо в браузере, начав разрабатывать некоторую оболочку (ссылка). Однако, споткнулся на вопросе производительности.

Если при открытии ссылки подождать несколько секунд и кликнуть пунтк меню «View» и отметить галочкой опцию «Pseudo Code», можно увидеть некий сгенерированный листинг, который будет завёрнут в «new Function("_", Pseudo_Code)»…
Мною ожидалось, что если вместо многократных циклов с «switch-case» и эмуляцией исполнения инструкций процессора всё перенести внутрь «new Function», то браузер сообразит, что нужно произвести хотя бы минимальную компиляцию кода…

Однако, если мышкой порисовать несколько линий на Canvas'е окошка «Graphics Display», то можно заметить жуткое подвисание браузера на момент исполнения той «Функции» с текстом из окошка «Pseudo Code»…
Очевидно, нужно всё оптимизировать и переносить на уровень WebAssembly!

То есть, как можно видеть из «Pseudo Code», выбросить все getter'ы и setter'ы в первую очередь!
А без них всё усложняется на порядки, так как если глянуть на реализацию одной операции сложения…
BigInt.prototype.PADD = function(n, mask) { // Packed Add
	return (((this & mask) + (n & mask))) ^ ((this ^ n) & ~mask);
}
…котор ая проще операции вычитания…
BigInt.prototype.PSUB = function(n, mask) { // Packed Subtract
	return (((this | ~mask) - (n & mask)) & mask) | ((this - n) & ~mask);
}
…стан овится очевиднее факт, что без прототипов и прочего сахара то самый «Pseudo Code» не будет уже таким изящным, как на данном этапе реализации оболочки…

Ясно, что WebAssembly не создавался для эстетики и служит своеобразным промежутком между JavaScript и псевдо-кодом, годным для трансляции на язык ассемблера конкретного процессора.

Но меня в первую очередь интересует вопрос: Неужели так всё плохо с производительностью getter'ов и setter'ов?
Нельзя ли частично ускорить код, поместив «"use asm"» внутрь многочисленных getter'ов и setter'ов?
Например, вот так:
BigInt.prototype.PADD = function(n, mask) {
	var _this = BigInt(this);
	'use asm';
	_this = _this|0n;
	n = n|0n;
	mask = mask|0n;
	return ((((_this & mask) + (n & mask))) ^ ((_this ^ n) & ~mask))|0n;
}
BigInt.prototype.PSUB = function(n, mask) {
	var _this = BigInt(this);
	'use asm';
	_this = _this|0n;
	n = n|0n;
	mask = mask|0n;
	return (((_this | ~mask) - (n & mask)) & mask) | ((_this - n) & ~mask)|0n;
}


Или нужно идти напролом без всякого сахара?
Может есть иные способы форсировать оптимизатор браузера?

Последний раз редактировалось Alikberov, 26.07.2022 в 02:40.
Ответить с цитированием