Я делаю простой трассировщик лучей на C++, используя SDL для графики и pthread для потоковой передачи. И у меня проблема с тем, что моя программа использует два ядра, работают нити, они просто не приводят оба ядра на 100%. Для интерфейса SDL я пишу непосредственно в его память, SDL_Surface.pixels, поэтому я предполагаю, что это не может быть блокировка SDL.Проблема с использованием pthread для использования нескольких ядер
Моя функция потока выглядит следующим образом:
void* renderLines(void* pArg){
while(true){
//Synchronize
pthread_mutex_lock(&frame_mutex);
pthread_cond_wait(&frame_cond, &frame_mutex);
pthread_mutex_unlock(&frame_mutex);
renderLinesArgs* arg = (renderLinesArgs*)pArg;
for(int y = arg->y1; y < arg->y2; y++){
for(int x = 0; x < arg->width; x++){
Color C = arg->scene->renderPixel(x, y);
putPixel(arg->screen, x, y, C);
}
}
sem_post(&frame_rendered);
}
}
Примечание: scene-> renderPixel является сопзЬ, поэтому я предполагаю, что оба потока могут читать из одной и той же памяти. У меня есть два рабочих потоков делают это, в моем главном цикле я делаю эти работы с помощью:
//Signal a new frame
pthread_mutex_lock(&frame_mutex);
pthread_cond_broadcast(&frame_cond);
pthread_mutex_unlock(&frame_mutex);
//Wait for workers to be done
sem_wait(&frame_rendered);
sem_wait(&frame_rendered);
//Unlock SDL surface and flip it...
Примечание: Я также попытался создать и соединение нитей вместо их синхронизации. Я скомпилирую это с помощью «-lpthread -D_POSIX_PTHREAD_SEMANTICS -pthread» и gcc не жалуется.
Моя проблема лучше всего проиллюстрировать на график загрузки процессора во время выполнения: CPU usage during execution. http://jopsen.dk/downloads/processor_usage.png
Как видно из графика, моя программа использует только одно ядро, в то время, а затем переключаться между ними каждый раз в в то время как, но это не приводит к тому, что на 100% когда-либо. Что в мире я сделал не так? Я не использую мьютекс или семафоры в сцене. Что я могу сделать, чтобы найти ошибку?
Также, если я поставлю while (true) вокруг scene-> renderPixel(), я могу нажать оба ядра на 100%. Поэтому я подозревал, что это вызвано накладными расходами, но я синхронизирую каждые 0,5 секунды (например, FPS: 0,5), учитывая сложную сцену. Я понимаю, что было бы нелегко сказать мне, что моя ошибка, но подход к отладке это тоже было бы здорово ... Я не играл с pthreads раньше ...
Кроме того, может ли это быть оборудования или проблема ядра, мое ядро:
$uname -a
Linux jopsen-laptop 2.6.27-14-generiC#1 SMP Fri Mar 13 18:00:20 UTC 2009 i686 GNU/Linux
Примечание:
Это помогло, также я обнаружил, что рендеринг каждой второй строки вместо половины изображения сделал два потока рендерингом почти в одно и то же время ... Поэтому мне в итоге удалось управлять обоими ядро до 100%, но это не улучшило мою частоту кадров :) - Или я просто измеряю это неправильно ... Спасибо за помощь ... – jonasfj
Ха-ха, первый шаг «оптимизации» всегда пытается сделать параллельный алгоритм, эффективный с n процессорами, чем последовательный с одним процессором. Продолжайте пытаться, вы в конечном итоге получите улучшение – Ben