ArenAK的博客

3D图形、虚拟现实 / 3D Computer Graphics,Virtual Reality

   :: 首页 ::  :: 联系 :: 订阅 订阅 :: 管理 ::
  21 随笔 :: 0 文章 :: 44 评论 :: 0 Trackbacks

现在的计算机大都采用多CPU或多核处理器,所以编程时尤其是在编写游戏或虚拟现实相关的程序时一定要充分发挥多核的能力,以加快程序运行速度,提高性能。常见的做法便是编写多线程的程序:在主线程中进行AI、碰撞检测和物理方面的计算,而在其它线程中进行渲染所需要的数据更新,比如计算各个Billboard的顶点坐标等等。

本文不讨论线程划分和线程负载的平衡问题。只简要说明在Windows系统中创建关闭线程及如何在线程中正确的使用Sleep函数。

1.         创建线程:用_beginthreadex(…)函数,此函数比具有同样功能的CreateThread(…)函数更安全。在微软Visual Studio .Net 2003的文档中说过用CreateThread创建线程后,用相应的ExitThread关闭线程时会出现小的内存泄露。

2.         关闭线程:用­_endthreadex(…)函数。

3.         Sleep的使用-举例说明

(1)虚拟现实程序中一个线程用于从硬件采集数据,隔20ms采集一次。
         
这样我们可以在采集的线程调用Sleep20),使得每采集一次数据后线程休息20ms。采集到的数据存在一个全局变量中,主线程每次都使用全局变量中的值。主线程的周期可以不与采集线程同步。

(2)图形程序中我们将某些复杂的生成顶点数据的算法放在辅线程里,可以在主线程进行AI运算的同时,辅线程进行生成顶点的运算(如计算噪声来生成顶点)。此时要求主线程走一个周期,辅线程的顶点更新也是一个周期。
        
这样我们可以在生成顶点的辅线程中调用Sleep0),并用一个全局的BOOL变量来控制两个周期的同步。
         Sleep
0)将线程剩下的时间片奉献给其他已经准备好的线程去用。
        
代码示例如下:


//
噪声生成顶点的线程
while(
线程没有退出)
{
       runOneStep();//
计算噪声生成顶点
       times++;
       g_bStepComplete = true;
       while(g_bStepComplete)
              Sleep(0);//
如果主线程还没利用新顶点,则此线程休息
}


//
主线程
while(...)
{
       AISimu();//AI
的计算
       while(!g_bStepComplete)
              sleep(0); //
如果生成顶点线程没有计算完则等待
       copyVBToBuffer(); //
将顶点线程生成的数据拷贝到渲染要用的Buffer
       g_bStepComplete = false;//
利用了新顶点后将标志变量复位
       Render(); //
渲染
}

4.   线程的安全问题十分重要。当多个线程同时操作一段数据时,安全起见,线程间的互斥是必不可少的。我通常利用thread mutex来做, 在此不再叙述。

--ArenAK--
posted on 2008-01-10 20:48 ArenAK 阅读(496) 评论(2)  编辑 收藏 所属分类: Programming

评论

#1楼  2008-01-30 10:50 hyh [未注册用户]
sleep(0)经过测试会造成100%的cpu占用,sleep的参数至少要为1,sleep函数的时间非常不精确,sleep(1)会占用10ms左右
  回复  引用  查看    

#2楼 [楼主] 2008-01-31 18:42 ArenAK      
@hyh
如文中所说,Sleep(0)只是将线程剩下的时间片奉献给其他已经准备好的线程去用,如果下个线程时间片到来则这个线程继续运行.而Sleep(1)则要线程休息够1ms(或许精度不高)才去运行,如果下个线程时间片到时线程休息时间还没到1ms, 则这个线程继续休息.
可以测试
while(1)
{
Sleep(0);
}

while(1)
{
}
这两者对CPU的抢占是"略有差别"的.
若要在渲染线程与主线程间最快的交换,恰恰可以利用这个小的差别.
  回复  引用  查看    


标题  
姓名  
主页
Email (只有博主才能看到) 
验证码 *  看不清,换一张
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2008-01-18 22:38 编辑过