Эффективная передача больших массивов с помощью Emscripten C ++ Web Worker: какой дизайн JavaScript лучше?

У меня есть Emscripten C ++ Web Worker, какой дизайн более эффективен для передачи больших данных в программу JavaScript?

Так как веб-работник делает clone() и сериализация, для передачи через систему сообщений веб-работника, здесь есть некоторые издержки. Также необходим некоторый код для перевода полученных данных на стороне C ++ из HEAP32 в массивы JavaScript ( C -> JS ).

Под эффективностью я подразумеваю, какой дизайн быстрее, т. Е. Какой дизайн приводит к меньшему запуску new а также gc() (конструирование и разрушение объектов JS). Мой Web Worker использует основную функцию, написанную на C ++, которая возвращает большие массивы (два массива float[V][3] а также int[N][3] с N = V = 10000. Он будет использоваться для обновления геометрии ThreeJS и будет вызываться десятки тысяч раз в течение длительного периода времени на веб-странице. Помимо того, что это медленно, это также может вызвать замедление работы браузера, зависание или сбой.

  1. Напишите веб-работника с использованием JS, который импортирует JS-код, компилирующий с использованием Emscripten Cons: Эта опция кажется невозможной, так как сторона веб-работника должна импортировать файл JS компиляции. Обмен данными: C++ -> JS -> message(serialise) -> JS, Дизайн: (C++)JS <-WW-> JS, файлы: core_mc_algorithm.cpp, worker.js, main.js.
  2. Используйте C ++ Web Worker, скомпилированный с использованием -s BUILD_AS_WORKER=1напишите другой код C ++ на главной стороне, которая получила данные, и преобразуйте результаты из HEAP в JS на главной стороне: (средство отслеживания данных WebWorker, обработанное Emscripten): Pros: эффективный перевод, но требуется два преобразования. риск: на стороне C ++ требуется многократное копирование из вектора в массив и т. д. Обмен данными: C++ -> message(serialise) -> C++ -> JS, Дизайн: (C++) <-WW-> C++(JS) , файлы: worker.cpp, main.cpp, main.js.
  3. Снова C ++ Web Worker, но с функцией веб-работника напрямую связывается основная программа, которая находится на JavaScript. Pros: Конверсии / обмены не делаются дважды. Между C ++ и JS нет отдельного обмена, это преобразование выполняется одновременно с сериализацией WW. риски: Декодирование может быть сложным и запутанным (необходимо будет повторно реализовать протокол, что само по себе требует многократных преобразований, что может быть не очень эффективным). Кроме того, обмен может быть неэффективным и не может улучшить производительность. Обмен данными: C++ -> message(serialise) -> JS, Дизайн: (C++) <-WW-> JS, файлы: worker.cpp, main.js.

У меня есть этот код на C ++, я хочу запустить его в качестве веб-работника:

void produce_object (
REAL* verts_output, int number_of_vertices,
int* faces_output, int number_of_triangles ) {
// Run Marching cubes, which produces a vector<int> and a vector<float>.
// fills in the arrays verts_output[] with coordinates (size: 3*number_of_vertices),
// fill in faces_output[] with triangle vertex indices (size: 3*number_of_triangles ), using some numerical code which includes the Marching Cubes algorithm.
}

Мне нужна следующая функция обратного вызова JavaScript для вызова с правильными параметрами. Это определено в файле HTML:

function update_mesh_geometry_callback (verts, faces) {
/* verts and faces are of type Float32Array and Int32Array of size (3*N) and (3*V). In this function they are used to create the following object, which is added to the scene.*/
var geo = new THREE.Geometry(verts, faces); // a subclass
scene.add(new THREE.Mesh(gro, mat, etc));
}

Типичный размер как минимум: number_of_vertices == 90000 = N, number_of_triangles == 8000 = V.

3

Решение

Я считаю, что вы после передачи. У работника есть дополнительный параметр в postMessage метод:
https://developer.mozilla.org/en-US/docs/Web/API/Worker/postMessage

Переводимые работают только с ArrayBuffers, они также сбрасывают буфер из потока сообщений, вы должны помнить об этом, но для вашего случая это выглядит как идеальное решение, так как это позволит избежать полного копирования.

вот пример кода игрушки для того, что вы бы имели в своем работнике

var vertices = new Float32Array(100000);
var faceIndices = new Uint32Array(50000);
postMessage({vertices: vertices, faceIndices: faceIndices}, [vertices.buffer, faceIndices.buffer]);

Вы можете прочитать больше о переводе здесь:
Использование переносимых объектов из Web Worker

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]