Простите меня за то, что я не являюсь экспертом в многопоточности, и мне нужна помощь. Итак, просто некоторые данные, прежде чем я перейду к своему вопросу:
Предварительные знания
- Разработка кода C++ на Jetson TK1
- Jetson имеет 4 ядра процессора (четырехъядерный процессор ARMv7)
- Из того, что я исследовал, каждое ядро может использовать один поток (4 ядра -> 4 потока).
- Я запускаю приложение компьютерного зрения, которое использует OpenCV.
- Захват кадров с веб-камеры, а также захват кадров из видеофайла
Псевдо-код Я пытаюсь оптимизировать свой многопоточный код, чтобы получить максимальную производительность для своего приложения. В настоящее время это базовая компоновка моего кода:
int HALT=0;
//Both func1 and func2 can be ran parallel for a short period of time
//but both must finish before moving to the next captured webcam frame
void func1(*STUFF){
//Processes some stuff
}
void func2(*STUFF){
//Processes similar stuff
}
void displayVideo(*STUFF){
while(PLAYBACK!=DONE){
*reads video from file and uses imshow to display the video*
*delay to match framerate*
}
HALT=1;
}
main{
//To open these I am using OpenCVs VideoCapture class
*OPEN VIDEO FILE*
*OPEN WEBCAM STREAM*
thread play(displayVideo, &STUFF);
play.detach();
while(HALT!=1){
*Grab frame from webcam*
//Process frame
thread A(func1,&STUFF);
thread B(func2,&STUFF);
A.join();
*Initialize some variables and do some other stuff*
B.join();
*Do some processing... more than what is between A.join and B.join*
*Possibly display webcam frame using imshow*
*Wait for user input to watch for terminating character*
}
//This while loop runs for about a minute or two so thread A and thread
//B are being constructed many times.
}
Вопрос(ы) Итак, я хотел бы знать, есть ли способ указать, какое ядро/поток я буду использовать при создании нового потока. Я боюсь, что когда я снова и снова создаю потоки A и B, они перескакивают на разные потоки и снижают скорость моей системы и/или чтение видео. Хотя это опасение не совсем оправдано, я вижу очень странное поведение на четырех ядрах при запуске кода. Обычно я всегда вижу одно ядро, работающее на 40-60%, которое, как я полагаю, является либо основным потоком, либо потоком воспроизведения. А вот что касается остальных ядер, то вычислительная нагрузка очень скачкообразная. Кроме того, во время игры в приложении я вижу, как два ядра загружаются с 60% до 100%, но эти два ядра не остаются постоянными. Это может быть первое, второе, третье или даже четвертое ядро, и тогда они сильно снизятся, обычно примерно до 20-> 40%. Иногда я вижу, как только 1 ядро падает до 0% и остается таким, что кажется другим циклом цикла while (т. е. захват кадра, процесс, поток A, поток B, повтор). Затем я увижу, что все четыре из них снова активны, что является более ожидаемым поведением.
Я надеюсь, что я не был слишком расплывчатым в этом посте. Я просто вижу, что у меня немного неожиданное поведение, и я хотел бы понять, что я могу делать неправильно или не учитывать. Спасибо всем, кто может помочь или указать мне в правильном направлении.
HALT
изmain
и из потокаplay
`. Поэтому программа выдает неопределенное поведение. У вас есть c++11? - person nwp   schedule 12.05.2015std::atomic<int> Halt;
(которую вам нужно вручную установить на 0), чтобы исправить это состояние гонки. То же самое касаетсяPLAYBACK
. ЕслиSTUFF
неconst
, у вас есть еще одна гонка. Создание и уничтожение потоков недешево, делать это в цикле излишне медленно. Вместо этого рассмотрите возможность использования пула потоков. Другая возможность - использоватьstd::async
, который может сделать это за вас. Вы должны убедиться, что у вас нет состояния гонки, которое требует медленной синхронизации. Однопоточный может быть быстрее и проще. - person nwp   schedule 12.05.2015