Итак, я работал над системой отслеживания в реальном времени с opencv. Пару дней назад мне пришлось начать использовать DirectShow (что было совершенно новым для меня), потому что мне нужно было более высокое разрешение от веб-камеры. Чем выше разрешение, тем выше использование процессора. Процессор работает на 50%, когда используется только directshow без ЛЮБЫХ алгоритмов opencv. (У меня двухъядерный = 100% использование одного ядра)
Теперь мне нужно расширить эту систему, чтобы она использовала оба моих ядра.
Я нашел этот хороший пример от Microsoft и смог запустить его, используя оба моих ядра:
void test1(){
parallel_invoke(
[]() { run1(); },
[]() { run2(); }
);
}
Это работает отлично, и я могу использовать около 85% от общего процессора (всего 2 функции с петлями и n вещей).
Теперь я хочу использовать это в моей другой системе. И я не знаю, как это сделать.
Краткое описание моей системы:
int main(){
startDirectshow()
};
startDirectShow(){
//code for creating the directshow filter graph. including iSampleGrabber filter.
}
sampleCallBackFunction(....){
// function called for every frame in the graph
}
Пока все работает, sampleCB вызывается для каждого кадра (или, по крайней мере, несколько кадров в секунду, кадры могут быть пропущены при использовании этого ?!)
Моя идея состояла в том, чтобы позволить sampleCallBackFunction () работать на втором ядре (я не хочу привязывать его к конкретному ядру, используйте только первое доступное)
Но пример, который я нашел, запускает обе функции одновременно, из одного и того же места. Можно ли каким-то образом сказать системе, что «sampleCallBackFucntion» должен работать на другом ядре?
Другая идея, которая у меня была, заключалась в том, чтобы просто сохранить данные в «sampleCallBackFunction ()», а также установить bool «newFrameAvailable» в значение true. И пусть другой поток извлекает данные из глобального массива.
while(true)
If (newFrameAvailable){
get-next-frame-in-buffer-and-do-opencv-algorithm();
}
else{
do-nothing();
}
}
Так. Мой вопрос: как заставить функцию вызываться из другой функции («sampleCallBackFunction» вызывается из «startDirectshow»)?
Спасибо!
Ваш вопрос не совсем понятен, но я полагаю, вы хотите позвонить sampleCallbackFunction
в другой теме. (функции обычно вызываются внутри другой функции, которая делает стек вызовов …)
Потому что DirectShow, ваш sampleCallBackFunction
Скорее всего, он уже запущен в потоковом потоке, который отличается от вашего основного потока. Конечно, все, что происходит в потоковом потоке, является бременем одного логического ядра.
Затем, если вы создадите еще один поток на sampleCallbackFunction
Ваша система достаточно умна, чтобы распределять работу по доступным ядрам, это не проблема. Но я сомневаюсь, если parallel_invoke
дает вам возможность делать то, что вы должны, и я предлагаю искать CreateThread
если вы действительно хотите сделать там другого работника.
Кстати: в приложении с графическим интерфейсом самый простой способ вызова функции в другом потоке заключается в использовании SendMessage
потому что вызов всегда распространяется на поток, который создал окно. Этот звонок, тем не менее, блокирует …
Прежде всего, вы можете лучше проверить, что именно перегревает ваш процессор до 50% без какой-либо обработки. Скорее всего, это преобразование в цветовое пространство RGB, которого вы можете избежать, обрабатывая видео в другом домене формата пикселей. Для захвата голого видео не требуются такие высокие значения загрузки ЦП.
Как заставить функцию вызываться из другой функции («sampleCallBackFunction» вызывается из «startDirectshow»)?
Это не совсем то, что вы хотите сделать, если хотите обрабатывать параллельно и / или продолжать захват во время обработки данных. startDirectshow
Поток является управляющим потоком, который запускает / останавливает обработку, а также запускает внутренний потоковый поток. Синхронизация с управляющим потоком не улучшит производительность, но принесет головную боль (а) затрат на синхронизацию и (б) шансов на завершение взаимоблокировки.
Если вы хотите обрабатывать параллельно, вам нужно скопировать данные в вашем примере обратного вызова граббера и выйти из него как можно скорее. Затем пул потоков, таких как TPL
или ваша собственная, будет выполнять обработку асинхронно, не влияя на производительность захвата.