распараллелить программу преобразования видео с помощью tbb

Итак, мне дана программа на с ++, и я должен распараллелить ее с помощью TBB (сделать ее быстрее). Когда я изучал код, я подумал, что использование конвейера имело бы смысл. Проблема в том, что у меня мало опыта, и то, что я нашел в Интернете, смутило меня еще больше. Вот основная часть кода:

    uint64_t cbRaw=uint64_t(w)*h*bits/8;
std::vector<uint64_t> raw(cbRaw/8);

std::vector<uint32_t> pixels(w*h);

while(1){
if(!read_blob(STDIN_FILENO, cbRaw, &raw[0]))
break;  // No more images
unpack_blob(w, h, bits, &raw[0], &pixels[0]);

process(levels, w, h, bits, pixels);
//invert(levels, w, h, bits, pixels);

pack_blob(w, h, bits, &pixels[0], &raw[0]);
write_blob(STDOUT_FILENO, cbRaw, &raw[0]);
}

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

Спасибо заранее,

Д. Христос

0

Решение

На самом деле вы можете использовать tbb::parallel_pipeline обрабатывать несколько видео «капель» параллельно.

Базовая схема представляет собой трехэтапный конвейер: входной фильтр считывает большой двоичный объект, средний фильтр обрабатывает его, а последний записывает обработанный большой двоичный объект в файл. Фильтры ввода и вывода должны быть serial_in_orderи средний фильтр может быть parallel, Распаковка и упаковка, по-видимому, могут быть выполнены либо на средней стадии (я бы начал с этого, чтобы минимизировать объем работы на последовательных этапах), либо на входе & выходные каскады (но это может быть медленнее).

Вам также необходимо убедиться, что хранилище данных (raw а также pixels в вашем случае) не распределяется между одновременно обработанными BLOB-объектами. Возможно, самый простой способ — создать хранилище для каждого блоба, которое передается по конвейеру. В отличие от последовательной программы, будет невозможно использовать автоматические переменные для хранилища, которое необходимо передавать между этапами конвейера; Таким образом, вам нужно будет выделить ваше хранилище с new во входном фильтре передайте его по ссылке (или через указатель) через конвейер, а затем delete после того, как вся обработка сделана в выходном фильтре. Это, безусловно, необходимо для raw место хранения. За pixels однако вы можете продолжать использовать автоматическую переменную, если все операции, которые в ней нуждаются, то есть распаковка, обработка и упаковка результата, выполняются в теле среднего фильтра. Конечно, объявление переменной должно также перемещаться туда.

Позвольте мне набросать модификацию вашего серийного кода, чтобы сделать его более готовым к применению parallel_pipeline. Обратите внимание, что я изменился raw быть динамически распределенным массивом, а не std::vector; код, который вы показали, по-видимому, в любом случае не использовал его как вектор. Имейте в виду, что это всего лишь эскиз, и он может не работать как есть.

uint64_t cbRaw=uint64_t(w)*h*bits/8;
uint64_t * raw; // now a pointer to a dynamically allocated array

while(1){
{ // The input stage
raw = new uint64_t[cbRaw/8];
if(!read_blob(STDIN_FILENO, cbRaw, raw)) {
delete[] raw;
break;  // No more images
}
}
{ // The second stage
std::vector<uint32_t> pixels(w*h);
unpack_blob(w, h, bits, raw, &pixels[0]);
process(levels, w, h, bits, pixels);
//invert(levels, w, h, bits, pixels);
pack_blob(w, h, bits, &pixels[0], raw);
}
{ // The output stage
write_blob(STDOUT_FILENO, cbRaw, raw);
delete[] raw;
}
}

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

1

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

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

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