我正在使用 SDL 和 Pthread 用 C++ 开发光线追踪器。我在使我的程序使用两个内核时遇到问题。线程可以工作,但它们不会 100% 使用两个内核。为了接口 SDL,我直接写入它的内存 SDL_Surface.pixels,所以我认为它不可能是 SDL 锁定我。
我的线程函数如下所示:
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 是 const,所以我假设两个线程都可以从同一个内存中读取。我有两个工作线程在做这件事,在我的主循环中我使用:
//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 使用图来说明:(
来源:jopsen.dk)
从图中可以看出,我的程序一次只使用一个内核,然后每隔一段时间在两者之间切换,但它永远不会将两者都驱动到 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
笔记: