AFAIK, при передаче массивов из JS в функции C / C ++, скомпилированные в Emscripten, мы по сути помещаем массив в имитируемый JS HEAP (например, Module.HEAPU8
), который разделяется кодом JS и кодом C / C ++.
Это прекрасно работает в однопоточной среде, но как насчет многопоточной среды, такой как рабочие потоки? Существует ли какой-то встроенный механизм, гарантирующий безопасность потоков для этого имитированного HEAP?
Если нет, значит ли это, что нам нужно позвонить Module._malloc()
& Module._free()
динамически управлять пространством кучи для каждого потока? Если это так, это звучит как потенциальное узкое место в производительности, поскольку усилия по копированию массива и выделению / освобождению пространства могут поставить под угрозу выгоду, которую мы получаем от использования рабочих потоков.
Ваше понимание верно, но в настоящее время невозможно поделиться WebAssembly.Memory
через рабочих. JavaScript имеет SharedArrayBuffer
но WebAssembly пока не поддерживает эквивалент (и совместим) WebAssembly.Memory
с shared=true
атрибут.
Как только он будет поддержан, вы сможете postMessage
WebAssembly.Memory
и использовать его для создания нескольких модулей вместе с рабочими. Вы также сможете postMessage
основной SharedArrayBuffer
и чтение / запись в него и из него с использованием JavaScript одновременно с WebAssembly.
Во всех этих случаях их память не будет скопирована. WebAssembly malloc
/ free
реализация не указана, но то, что вы получите, например, Emscripten будет потокобезопасным. Не будет использовать grow_memory
Первоначально (дизайн в настоящее время запрещает наращивать общую память), но скорее предварительно выделит и удостоверится, что это потокобезопасно для вас (как и любая многопоточная реализация C).
Других решений пока нет …