Как стать автором
Обновить

Комментарии 9

Спасибо ! Сейчас немного занят, утащил в закладки !

Нда... Демка доставляет... Всё видно абсолютно наглядно. От 6.3 - 7 на CPU-js до 700-800 на GPU. Спасибо, жду продолжения ! Сейчас немного раскидаю дела, буду изучать как это работает.

Осталась одна небольшая загвоздка: память с каждым вызовом загрязняется. Если вы попробуете порисовать фрактал много раз и при этом будете выводить значение указателя на буфер, то увидите, что оно с каждой отрисовкой растёт:

И при продолжительном рисовании у вас рано или поздно закончится память, с чем вас радостно поздравит такая ошибка:

Чтобы этого не происходило, нужно чистить буфер после каждой отрисовки

Неправда, чтобы такого не происходило — надо принимать буфер в generate_fractal_image параметром, а не создавать его каждый раз.


Поэтому, чтобы инвертировать комплексное число, надо посчитать его норму, поделить реальную часть на неё, а мнимую — на её отрицательное значение

Неправда, чтобы инвертировать комплексное число — следует воспользоваться функцией inv:


sum += diff.inv();

Неправда, чтобы такого не происходило — надо принимать буфер в generate_fractal_image параметром, а не создавать его каждый раз.

Как вариант. На практике в онлайн демо работа с буфером происходит практически также: буфер создаётся в JS (через wasm), а потом в функцию отрисовки передаётся указатель на этот буфер. Но после заполнения картинки буфер удаляется.

Неправда, чтобы инвертировать комплексное число — следует воспользоваться функцией inv

Если не оптимизировать вычисления, то можно обойтись и функцией diff.inv() или выражением 1.0 / diff. Здесь же речь о том, как 2 раза не считать одно и то же: вначале мы используем норму чтобы проверить близость точки, а потом используем её для инверсии diff:

let mut diff = z - root;
let square_norm = diff.norm_sqr();
if square_norm < MIN_DIFF {
   return z;
}
diff.re /= square_norm;
diff.im /= -square_norm;
sum += diff;

Здесь же речь о том, как 2 раза не считать одно и то же

На собственном опыте сталкивался с тем, что компилятор в profile release оптимизирует подобные конструкции. В бенчмарке не было значительной разницы между вынесенной переменной и многократным вызовом функции.

Решил проверить на godbolt (ссылка). В слегка упрощенном примере из поста с 3-мя вызовами inv функция вызывается 1 раз, а значение храниться на стеке.

У меня в Firefox на Kubuntu демка не работает, не рисует фрактал. В Brave работает.

В консоли лисы при этом:

`WebAssembly.instantiateStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:
 TypeError: WebAssembly: Response has unsupported MIME type 'text/html; charset=utf-8' expected 'application/wasm' newton_fractal.js:188:29
CompileError: wasm validation error: at offset 4: failed to match magic number module-workers-polyfill.js line 1 > Function line 197 > WebAssembly.instantiate:197
`WebAssembly.instantiateStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:
 TypeError: WebAssembly: Response has unsupported MIME type 'text/html; charset=utf-8' expected 'application/wasm' 2 newton_fractal.js:188:29
CompileError: wasm validation error: at offset 4: failed to match magic number module-workers-polyfill.js line 1 > Function line 197 > WebAssembly.instantiate:197
...

Это из-за модульных веб-воркеров. Довольно странно, потому что на локальном сервере полифилл работает. Возможно гитхаб ломает его.

Плюсую. Такая же штука, только пишет в режиме инкогнито:

Uncaught (in promise) DOMException: Worker.postMessage: The WebAssembly.Memory object cannot be serialized. The Cross-Origin-Opener-Policy and Cross-Origin-Embedder-Policy HTTP headers can be used to enable this.

И в обычном режиме похожую лапшу:

CompileError: wasm validation error: at offset 4: failed to match magic number

Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.