孟岩ID:myan
[修改头像]
1552932次访问,排名6好友1人,关注者32
总是在思考存在的问题
myan的文章
原创 146 篇
翻译 0 篇
转载 3 篇
评论 5196 篇
最近评论
lschou520:怎么会忘记印度、日本和欧洲呢?
daijunhua:支持,中华儿女,互相护持地走!
ranzj:我只抱怨自己的努力不够。
ranzj:我毫不怀疑 SilverLight 是个“钱”途无量的玩意儿。
winvc:还有 之前已经看到过一篇署名孟岩的文章了 也是自称学计算机的 在MOP发的文章 题目是《不知名的程序员写给想学编程的朋友》(最后署名前还特别声明了下自己是初中文化全靠自学的 大哥 这样的人全国有几千万 没几个比你这种货色差的)

那文章是看的我想吐 不知道是你还是重名了 不过咋跟你这篇文章风格这么像呢 都是不懂 逻辑混乱 瞎喷
你是自己想不明白问题 但认为自己想……
软件项目交易
订阅我的博客
XML聚合  FeedSky
订阅到鲜果
订阅到Google
订阅到抓虾
订阅到BlogLines
订阅到Yahoo
订阅到GouGou
订阅到飞鸽
订阅到Rojo
订阅到newsgator
订阅到netvibes
文章分类
收藏
    相册
    测试
    友情链接
    老赵的博客
    存档

    原创 “生命游戏”的多线程算法思考

    新一篇: 程序员必须走向专业化

    Intel正在ISN网站上举办一个多线程编程大赛,值得关注。Intel过去几年举办过好几次线程技术大赛,包括与topcoder合作的一些竞赛,质量都不错。题目难度适中,而且具有启发性,对多核编程感兴趣的C/C++程序员应该关注一下。其实参与这样的活动,置身于竞赛气氛当中,无论是否获奖,都可以在短时间内大幅度地提高对多线程编程的理解。这次比赛比较有特色,为期长达几个月之久,而且每个月都有一轮竞赛,每月评选一轮优胜奖,奖品也很诱人,是一颗4核的酷睿2CPU ;-)

    本月(2008年1月)的题目是一个经典问题“生命游戏”。这是英国数学家John Conway发明的一个有趣的游戏。不过这个游戏之所以名声大噪,还得归功于著名科普作家马丁•伽德纳。他在1970年10月号的《科学美国人》杂志“数学游戏”专栏介绍了生命游戏,不但让大众迷上这个游戏,也令多专业数学家产生了研究的兴趣,甚至产生了一个新的数学研究领域cellular automata(细胞自动机?),听说这个领域还对模拟类游戏产生了影响,不知是否确有其事。

    大致来说,生命游戏是这样玩的。在一个由正方形小格子组成的二维网格(就像国际象棋棋盘那样)里,生活着一群细胞。每一个细胞占据一个小格子。它的四邻左右(最多)有8个格子,如果那些格子里也生活着细胞,那么这些细胞就成为“邻居”。

    细胞对生存环境要求苛刻,太孤独的话会死。但是食物有限,所以太拥挤也会死。细胞还需要繁衍生息,如果邻居数量合适,就可以在空格子里分裂出新的细胞。数学家们研究的话题是,怎样制定规则才能让细胞群的繁衍发展呈现某种特定的模式,比如说,能够稳定持续地发展下去,或者逐渐消亡,或者恒定不变,或者,最有趣的是,在几个状态之内反复循环。要想“生生不息”,这些条件即不能太严苛,也不能太宽松。总之,Conway对于生命游戏制定的规则如下:

    1.    如果一个细胞只有0或1个邻居,它将因为孤独而死;
    2.    如果一个细胞有4到8个邻居,它将因为拥挤而死;
    3.    如果一个细胞恰有2或者3个邻居,它将继续生存下去;
    4.    如果一个空格子恰有3个邻居,将“生”出一个新细胞;
    5.    其他的空格子继续维持原状。

    这个问题出现在程序员面前的时候,大多数是要求开发一个程序来对这个游戏进行模拟。我以前学习数据结构和算法的时候曾经接触过,但是没有深入思考。其实这个问题很有趣,算法上可以有些变化,但主要是数据结构的设计,可以有几种不同的考虑。比如可以从网格角度出发,设计一个(可能是稀疏的)矩阵,用0或1表示细胞的生死,每过一代就对矩阵进行一次全局扫描,决定细胞的生死。也可以从细胞出发,把每个细胞的二维坐标位置记下,然后一个细胞一个细胞地考察,没考察一个细胞,就把它可能影响到的其他细胞或者空格纳入视线,等到全部细胞考察完毕,也就可以一次性决定下一代的格局。后面这种算法减少了需要考虑的情况数量,当网格很大而细胞比较稀疏时就节省了时间。

    不过这次Intel的竞赛并不想让参赛者在算法上动脑筋,而是已经把串行程序实现了,要求参赛者在其基础上改成并行多线程程序。可以从竞赛站点上分别下载LinuxWindows版的串行程序实现。其中的算法基本上是上述第二种,即从细胞出发的算法。程序当中自制了一个超级简单的链表数据结构,然后用四个链表newlive, newdie, maylive, maydie,分别表示新生的,刚死的,可能出生的和可能死掉的细胞。然后用TraverseList函数遍历链表,并对链表中的每一个元素施加相应的操作。最后把结果一口气写在一个5002x5002的网格中。实际上这个网格的有效尺度是5000x5000,多出来的那两行和两列,是为了方便边界条件的处理。整个算法还是很直白的,建议有兴趣的人直接下载程序来阅读理解。

    我大致思考了一下,实际上这个题目还是属于一个数据并行的算法,关键在与把链表的访问函数并行化,包括ClearList,TraverseList,CopyList,如果能够充分并行化,则可以利用多核CPU的多个硬件线程加速程序的执行。如果是为了这个目标,简单的单链表就似乎不是最好的数据结构,而类似STL中std::vector那样的动态数组就比较适合,因为可以很有效的分段。我的大致想法如下:

    用std::vector取代List作为基本数据结构,设定一个合适的grain size,也就是说一个线程处理的细胞数量。一般来说,这个数量的大小大致以需要消耗10,000条机器指令为好,我估计在这个例子中,100是一个合理的数值。然后根据现有细胞数量,确定线程数N。主线程创建N个线程后调用join阻塞自己,等待那N个线程分别在List的不同片段上执行相同的操作。当所有的线程执行完毕之后,就可以得到所需的结果。这里还应该用线程池来避免频繁地创建线程。至于算法,直接用程序中提供的即可。这个题目主要还是考察线程操作。

    这里的难点还是在那些底层的线程API。我不太熟悉pthread,对Windows线程还是比较熟悉的。尽管如此,让我去写一个小的线程池,然后再把每一个片段任务分配给线程来执行,再处理同步什么的,还是有点麻烦。直接使用OpenMP或者Intel Threading Building Blocks就会方便很多。我倾向于使用后者,不过还需要学习。

    这是我的是一些思考,有兴趣的朋友不妨试试做一下这个题目。

    Intel线程挑战赛的网址是:
     http://softwarecontests-zho.intel.com/threadingchallenge/

    在网页下方可以看到这个题目的详细信息,并且可以下载串行范例代码。








     

    发表于 @ 2008年01月21日 11:30:00|评论(loading...)|编辑

    旧一篇: 终于有人说出来了——Java不适合于作为主要编程教学语言

    评论

    #housisong 发表于2008-01-21 14:30:44  IP: 121.35.128.*
    我参加过一次intel的多核优化比赛,得了一个ipod
    为了并行算法我包装了一个用于并行计算的线程池类CWorkThreadPool,源代码参见
    <并行计算简介和多核CPU编程Demo> http://blog.csdn.net/housisong/archive/2007/01/17/1485166.aspx 使用比较简单,自己分割好任务,然后使用CWorkThreadPool类的回调就可以了;
    生命游戏上大学的时候写个一个;我觉得使用并行优化的同时也不应该放弃单线程上的优化,能获得非常大的性能收获,不会比并行的收益少; 关于使用稀疏矩阵的优化,从我的经验来看,迭代的次数要非常多代以后才可能有效(很多随机开局在最后都可能限于稀疏(陷入循环吸引子)和死亡(限于点吸引子))
    #Solstice 发表于2008-01-21 20:27:27  IP: 116.227.20.*
    cellular automata --- 元胞自动机。
    #Ivony 发表于2008-01-22 11:18:39  IP: 218.80.240.*
    我所能想到的最简单的办法就是分块并行处理。
    把5000*5000个格子分成8份,每份是1200*1200大小,加上边界是1202*1202,用八个线程同时计算八份,然后计算边界。
    只需要一个很好的边界计算算法,就可以直接沿用现成的算法变成多线程计算。
    #Ivony 发表于2008-01-22 11:25:43  IP: 218.80.240.*
    嗯,MS边界处理都不用那么麻烦,每一块计算1201*1201大小,同时结果只取1200*1200大小,这样就没有边界冲突问题……
    #llwu 发表于2008-02-18 06:43:16  IP: 86.136.52.*
    楼上只增加1的边界可靠吗?能不能严格证明这样可以避免重叠的相互影响。

    另外,这个题目本身我认为不太严密。每个规则和每个细胞的执行顺序不同有可能导致 下一状态不同。
    #passos 发表于2008-02-24 03:17:05  IP: 58.83.246.*
    想到GPGPU了
    #zkkpkk 发表于2008-03-17 16:23:24  IP: 116.252.190.*
    每个规则和每个细胞的执行顺序不同有可能导致 下一状态不同
    =====================================
    不太懂你说的,这游戏本身不就是玩的这个吗?去预料发展格局是玩家的问题。
    发表评论  


    当前用户设置只有注册用户才能发表评论。如果你没有登录,请点击登录
    Csdn Blog version 3.1a
    Copyright © 孟岩