使用并行线程问题利用多个核
题
我使用SDL和Pthread的显影++光线跟踪器在℃。我在做我计划利用两个核心问题。该线程的工作,但他们不使用双核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是常量,因此我假定两个线程可以从相同的存储器中读出。 我有两个工作线程这样做,在我的主循环使用我做出这些工作:
//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%如初。 在世界上我做了什么错?我不使用场景中的任何互斥体或semaphors。 我能做些什么来寻找错误的?
另外,如果我放而(真)周围scene-> renderPixel()我可以两个核心推到100%。所以我怀疑这是造成的开销,但我只同步每0.5秒(FPS例如:0.5),给定一个复杂场景。 我意识到这可能不容易,告诉我我的错误是什么,但一种方法来调试这将是巨大的。我以前没有......与并行线程起到
另外,可以在此是一个硬件或内核的问题,我的内核是:
$uname -a
Linux jopsen-laptop 2.6.27-14-generic #1 SMP Fri Mar 13 18:00:20 UTC 2009 i686 GNU/Linux
注意:
解决方案
这是无用的:
pthread_mutex_lock(&frame_mutex);
pthread_cond_wait(&frame_cond, &frame_mutex);
pthread_mutex_unlock(&frame_mutex);
如果你等待,等待一个新的框架做这样的事情:
INT新帧= 0;
第一线程:
pthread_mutex_lock(&mutex);
new_frame = 1;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
其他线程:
pthread_mutex_lock(&mutex);
while(new_frame == 0)
pthread_cond_wait(&cond, &mutex);
/* Here new_frame != 0, do things with the frame*/
pthread_mutex_unlock(&mutex);
pthread_cond_wait()的,实际上释放互斥锁,并取消调度的线程,直到该条件获得信号。当该条件获得信号的线程被唤醒并互斥再吸收。所有这些都发生在调用pthread_cond_wait()函数内部
其他提示
我走在黑暗中刺野,说你的工作线程正在花费大量的时间等待条件变量。在这种情况下你的代码主要是CPU密集型获得良好的CPU性能,它被理解为使用编程,你把线程作为一个“池子”的面向任务的样式,您可以使用一个队列结构喂工作他们。他们应该花时间极少量的工作拉从队列和大部分时间在做实际的工作。
您现在所拥有的是什么的情况下,他们可能正在做的工作了一段时间,然后通过旗语,他们完成通知主线程。直到两个线程都完成它们当前处理帧上工作主线程不会释放它们。
由于使用C ++,你认为使用如Boost.Threads?它与多线程代码更容易的工作,和API实际上是一种类似于并行线程,但在“现代C ++”的一种方式。
我不是并行线程大师,但在我看来,下面的代码是错误的:
pthread_mutex_lock(&frame_mutex);
pthread_cond_wait(&frame_cond, &frame_mutex);
pthread_mutex_unlock(&frame_mutex);
要报价这篇文章
pthread_cond_wait()
阻塞调用 线程,直到指定的条件 发出信号。这个程序应该是 调用时互斥已被锁定,并 会自动释放互斥 在等待。经过信号 接收线程被唤醒,互斥 将被自动锁定,无法 由线程。程序员然后 负责解锁互斥时 线程完成它。
所以在我看来,你应该被释放后的互斥 的代码follwing的pthread_cond_wait
块。