最近阅读了《GAME PROGRAMMING GEMS6》,颇有收获,以笔记之。
首先是GENERAL PROGRAMMING SECTION。
1.2 Utilizing Multicore Processors with OpenMP
OpenMP是一个并行库,和一般的多线程库不同,OpenMP着重于局部和片断的并行,目前VC8.0和GCC4.2均已支持了OpenMP。
(a)OpenMP的并行方式
在我未接触OpenMP之前,我通过多线程只认识到并行其实和多进程并行没有什么区别,比如UI线程和工作线程,又比如渲染线程和后台装载线程。
它们是两条生命期长得不得了的线程,通过临界区和互斥体访问共享变量,协同完成任务。
我一直觉得这样的并行挺危险的,在这长长的生命周期中,它们无法判断对方目前正处于何种状态,只能通过加锁来解决沟通问题。
OpenMP的并行是局部的并行,线程的生命周期较短,并且处于同一状态。在串行程序中,程序可以分为许多有序的任务,像流水线般,如
step1->step2->step3->step4->step5。
OpenMP就是针对某一个step,来展开并行处理的。比如之前的5个step,其中step2和step5使用了并行处理,那么每一步都线程数量如下(假设是双核,那进入并行时产生4个线程):
1->4->1->1->4。
一般能够展开并行的任务最好是for循环的任务,这种任务可以将被处理的数据均分到多个线程上,并行处理。
如:
for n=0,100
proc( data[n] );
就可以被OpenMP展开为以下4个循环,每个循环分配一个线程:
for n=0,25
proc( data[n] );
for n=25,50
proc( data[n] );
for n=50,75
proc( data[n] );
for n=75,100
proc( data[n] );
(b)什么样的task应该交给OpenMP并行?
由上面的例子可以看到,一般是for循环的task,可以交给OpenMP。但是这里还是有些需要注意到地方的,比如在处理data[i]的时候,就不要去访问data[j]的数据,也就是尽量不要写出一些需要加锁访问的代码。即使在处理某个数据的时候要访问其他相关的数据,这样的数据需要多数也是可以在进入并行区域前准备好的:
获取(串行)->处理(并行)->回写(串行)
(c)OpenMP的使用接口
不要在正式程序中太着急的使用OpenMP,先老老实实的写你的串行程序,然后在程序完成后经过测量找出热点,再对某些热点使用OpenMP并行。说到这里,你应该感觉到,OpenMP是一种想要就要,不破坏程序原有结构的东西了吧。
没错,OpenMP简单用的话简单无比,复杂用的话也不是那么困难。
比如:
#pragma omp paralle for
for ( int i=0; i < 1000; ++i )
proc( data[i] );
#pragma omp指令在编译器的支持下,就会展开成许多东西,并切实的发生并行。
由于并行一向不好调试,所以一开始要做的就是,串行编程,然后运行无措,最后才优化,不是吗?
(d)使用OpenMP的必要性
在游戏开发中,有两种程序必然要OpenMP的并行,一种是MMOG的服务器程序,上面跑着近万NPC和子物体,再加上几千玩家,这样的处理量,不需要多核不需要并行是不可能的。另一种就是游戏机游戏开发,比如X360,就是几个低能的CPU凑在一起拼出来的,这要是不并行,那铁定没法跑了。
高频的CPU估计是很难再有了,进入多核时代,不用多线程,不用并行,出门都不好意思跟人打招呼····
PS:在看本书之前,我就已经由X360的朋友介绍,进行了OpenMP的研究,有一种与主流同步的感觉+ω+
1.3Computer Vision in Games Using the OpenCV Library
(a)OpenCV是一个视觉,图像处理库,比如能从照片中识别出人脸之类的
(b)OpenCV是Intel发起的,所以在Intel的平台上效率会优于AMD平台
(c)有兴趣的可以用OpenCV做出itoy这样的游戏,也就是使用camera操作的游戏
我个人对OpenCV目前不是很有兴趣,不过公司里面还是有人玩过一段时间,又一次觉得和主流同步了+ω+
好,累了,今天先写到这里,剩下的慢慢出。
posted on 2007-11-24 10:14
LOGOS 阅读(2067)
评论(4) 编辑 收藏 引用 所属分类:
《GAME PROGRAMMING GEMS6》读书笔记