作者:孟岩 来源:CSDN博客 酷勤网收集 2007-09-01
究竟普通开发者是否需要面对多核,这个问题在很多地方都在讨论。很多人都认为不需要,这样说是基于过去几年的经验,认为目前的一般应用单核高速CPU已经足以应付,今后也没有新的重要应用驱动我们使用多核CPU,多核CPU要么是厂商狗急跳墙,要么是仅供科研计算,谢绝参观。
我不这么认为。
可以从两个角度来认识这个问题。
其一,现在单核CPU已经逐渐淡出市场,新生产的机器全部是双核。因此未来新增的计算机全部都会是多核,这是不以软件开发者意志为转移的。同样不以我们意志为转移的是,在激烈的竞争中,更有效地运用用户资产、提供更优异性能、更强壮的稳定性的一方会占据优势。你可以继续向用户重复说,其实单核就够了,没必要改进程序。你的用户也许会相信你一时,但是长期来看,当他的机器有4个核,8个核的时候,他一定会迁徙到更能够有效运用其机器资源的方案上去。结论是,竞争导致程序的多线程化势在必行。
也许这个观点不是那么有说服力。你可能会说,你可以凭借其它的优势稳住客户,并且这些优势肯定不会被对手抄袭。但愿你好运。可是第二个潮流恐怕就无法抗拒了。那就是新的应用。
1980-2000,曾经在将近20年的时间里,硬件的能力与软件对CPU的贪婪一直齐头并进,打造了软件最辉煌的20年。然而2000之后,我们似乎陷入了一个CPU计算能力过剩的时代。突然一下子大家感到没必要追逐CPU主频了,因为现有的计算能力完全够用,而且也想不出新的应用。于是很多人觉得,软件的历史终结了。
这是完全错误的。
我认为这几年出现的CPU计算能力过剩、新型应用发展停滞只是一个带有迷惑性的假象。造成这个假象的原因有三点,一是互联网的爆发转移了软件创新的重心,而网络带宽和可靠性均不理想,成了制约计算机整体performance的短板,相对来说,CPU的计算能力反而成了长板,显得过剩了。二是互联网使得计算向服务端集中,从而弱化了对客户端计算能力的需求。三是信息家电、数字家庭、Internet连入设备、民用机器人的发展仍处于初级阶段,新的计算平台还不成熟,人们的思路一时被束缚在成熟的PC平台上,无法展开。
然而上述三个问题都将会被一一破解,从而唤起对多核力量的渴望。
首先,网络带宽会迅速提升,使得一些新的应用出现,尤其是高质量的在线视频和视频交互应用(如远程教学,远程医疗)会对CPU运算能力提出前所未有的挑战。现在大家都习惯了模模糊糊、时断时续的网络视频,我相信5年以后我们一定会感叹自己当年的忍耐力。其次,互联网应用的发展趋势,RIA,尤其是P2P向传统应用的渗透,使得计算重回客户端。未来我们的机器可能不会是真正意义上的是Personal Computer,而是Community Computer或者Social Computer,在由计算机组成的社群里承担一份义务,这就会对普通电脑提出新的计算要求。举一个例子,未来你可能会受邀加入一个免费的视频电话网络,条件是你必须允许你自己的笔记本在线时充当一个路由器。你会如何选择?第三,新的计算设备将会在未来几年内发展起来,这些设备上可能没有成熟的操作系统,或者虽然有成熟的基础平台,但是没有足够理想的抽象层,同时对于可用性、可靠性的要求远高于PC。开发者将不得不亲手处理一些系统级的细节,在这种情况下,多线程程序设计的技术会变得非常重要,机会属于那些能够驾驭并充分发挥硬件能力的程序员。
综上所述,从现在算起,2-3年之内,多核程序设计(其实就是多线程程序设计)将成为软件开发领域的热门主题。这是我的一个估计,且拭目以待吧。
原文链接:http://blog.csdn.net/myan/archive/2006/07/28/994366.aspx
评论区:
# DSharp 发表于2006-08-06 10:37:00 IP: 61.147.119.*
TrackBack来自《我也来说说多核》:
硬件多核化将会让多线程前所未有的变的重要,软件的性能,更多的由多线程设计的好坏来决定。
# lpspider 发表于2006-07-28 19:12:00 IP: 219.236.209.*
好,孟岩的观点就是高屋建瓴。顺便说一下,微软的VC++2005里面已经没有单线程连接库了。
# myan 发表于2006-07-28 20:23:00 IP: 219.236.52.*
谢谢lpspider指出。我还想指出的是,VC8.0编译器直接支持OpenMP 2.0标准,在Intel C++ 7.0~9.0与VC8.0之间的OpenMP相关代码具有可移植性。
# redsea 发表于2006-07-29 04:06:00 IP: 61.144.97.*
前段时间做一个网络分析设备的计划,可以用到8核的cpu, 不过问题不在这里了,而是内存带宽似乎不太够用,需要尽量优化数据结构,使得访问量最大的数据能够全部被cache, 其他连续访问的数据物理地址要顺序,才能有最大的ram 输出带宽。
PC 上以后恐怕也有这样的时候。
# redsea 发表于2006-07-29 11:32:00 IP: 61.144.97.*
主页的资金供应到明年会有点问题,朋友从中国电信得知对某个分析设备有些需求,分析了一下做某个网络分析设备的能力和需要的时间,然后朋友和中国电信进一步接触,看看做这个东西是否能够解决明年主业的资金问题。
这个过程中,发现如果用较通用CPU 体系接近的network processor 处理2.5G bps以上的流量级别,做包的深度分析的话,cpu mips 通常都不是限制问题 8 core, 16core 64bit mips cpu 的都有,但是memory bandwidth 就很成问题。
# redsea 发表于2006-07-29 11:38:00 IP: 61.144.97.*
说到muiti core, 我表弟今年要从加大博士毕业了,准备选择的方向是multi core 优化的matlab。matlab 每年在美国的销售额不小。
不过我不懂, multi core 的语言实现,和smp 的语言实现方面上会有这么大的不同,可以作为相关产业的一个方向。我仅仅只是知道,multi-core system 很有可能用 share cache, 这样根据cache 相关性安排thread 给cpu 的算法可能有点不同, 动态内存分配可能对cache 相依性做优化,其他就毫无认识了, 呵呵。
# myan 发表于2006-07-29 22:58:00 IP: 219.236.55.*
我上次看了一个AMD的资料,L1 Cache是独立的,L2 Cache以后可能共享。这个影响当然很大,跟SMP大不相同了。
# laoeyu 发表于2006-07-29 23:52:00 IP: 221.137.253.*
呵呵。
说CPU过剩,让我想到bill曾说内存够了。
CPU的多核趋势,从技术上说主要是因为内存技术发展太慢跟不上CPU的速度,还有更为重要的原因就是工艺的问题,散热太厉害,为了提到主频,你看Intel的CPU的功耗,热量。Intel的P4甚至需要特别的大功率电源,Intel甚至提出了新的机箱标准:BTX。呵呵。
从宏观概念上来说,我想多核也只是从计算throughput的能力。
不过许多应用的都是对CPU的throughput都有要求,不管是Database还是App Server, Web Server。CPU的多核对我们Sofware Guy来说都是个好消息。
建议myan看看AMD Opteron和Sun的SPARC T1的材料。在这方面,他们走的比Intel更早也更好。
# laoeyu 发表于2006-07-30 00:13:00 IP: 221.137.253.*
Memory Bandwith的问题,说的应该是主板上内存。
AMD和Sun都较早的讲内存控制器集合到CPU内部直接控制管理,Intel不知道想在是不是也这样,其实这也就是为什么先前主频不占优势的情况下,AMD的CPU性能比Intel强的地方。
即使这样,内存的存储速度还是远不及CPU的速度。这里有个不错的方法,那就是 Sun推出的CMT技术,利用CPU和内存两个速度之间的差异,大概(4:1)的差异,同一个内存存取周期,同一个CPU Core内多跑三个CPU指令(来自其他的线程)。 Sun推出的UltraSPARC T1,就是一个CPU内有8个核,每个核通过CMT技术,就可以运行4个线程,也就是总共可以运行32个线程。
可以参考这篇文章:
http://blog.gceclub.sun.com.cn/index.php?op=ViewArticle&articleId=907&blogId=4
至于Cache, 还好并不是严重瓶颈,虽然是独立,但是也有"就近"的学问,就是NUMA,, Solaris X86也支持该方式。
# redsea 发表于2006-07-30 14:51:00 IP: 222.50.36.*
>>即使这样,内存的存储速度还是远不及CPU的速度。这里有个不错的方法,那就是 Sun推出的CMT技术,利用CPU和内存两个速度之间的差异,大概(4:1)的差异,同一个内存存取周期,同一个CPU Core内多跑三个CPU指令(来自其他的线程)。 Sun推出的UltraSPARC T1,就是一个CPU内有8个核,每个核通过CMT技术,就可以运行4个线程,也就是总共可以运行32个线程。
这个技术能够起作用的话, 前提还是计算能力是瓶颈, 某个logic core 等待内存的时候, 同一个physical core 的另外一个 logic core 运行条件已经 ok 了,就切换logic core运行.
内存带宽跟不上 cpu 的速度, 已经很多年了. CMT, 超线程可以解决: 短时间内跟不上需要的时候, 可以让数据已经就位的计算任务先做. 但是如果项目内存带宽本来不够, 这个也没有用.
这次这种经历, 对我来说也是初次碰到, 所以我详细一点说说看, 比较有趣.
我提到的分析设备最初给出的需求下: 10G 光纤下面, 下游250个C 类子网做针对每个tcp 连接, udp 包的基于内容深度分析和统计, 深度分析包括分析出tcp/udp 的协议类型, 以及跟踪ftp, h323 之类的动态端口协议, 识别出其内部动态分配的端口, 作为后续的分析的基础.
每个packet 64byte, 每秒钟 15M packet, 读入内存用掉 960M bytes, 写出的时候用掉 960M bytes, 对于每个packet, 光是比较src ip, dst ip 分析出它是哪个子网, 要用 src, dst 对250个地址做比对, 15M * 8 byte = 120M, 这还没有开始对包进行任何分析, 还没有对每个子网, 每个 ip 的各种不同流量做统计, 已经用掉了 2G bytes 带宽了.
现有的PC 体系, 内存连续访问的时候, 双通道配置的客户机内存带宽也就 5~7G/seconds, 服务器顶多也就8G 左右, 而network processor 比PC 还不如, 只有3~4G. 非连续访问的时候, 带宽更加糟糕.
所以这个项目, cpu 计算能力先不论, 首先考虑内存带宽是否够用. 用硬件芯片做ip 地址查找和正则表达式分析, 可以省掉很多带宽消耗, 最频繁的数据结构设计得可以被2M 的 l2 cache 缓冲, 也可以节省很多带宽.但是最后结论还是, 用这个体系np, 单一np做不了这个事情, 内存带宽不够, cpu 能力用不着去分析了.
如果内存带宽够用的时候, 这类型 np 的计算能力是很可观的. mips 64 np 里面, 高端的产品, 有 16 core, 每个 core 4 个 thread 的 -- 这里的 thread, 不是 OS 的thread, 而是类似 sun CMT, intel hyperthread 那种, 等待内存的时候, 可以切换执行的名词, 在mips 64 里面用的术语.
# redsea 发表于2006-07-30 14:57:00 IP: 222.50.36.*
>每个packet 64byte, 每秒钟 15M packet, 读入内存用掉 960M bytes, 写出的时候用掉 960M bytes, 对于每个packet, 光是比较src ip, dst ip 分析出它是哪个子网, 要用 src, dst 对250个地址做比对, 15M * 8 byte = 120M, 这还没有开始对包进行任何分析, 还没有对每个子网, 每个 ip 的各种不同流量做统计, 已经用掉了 2G bytes 带宽了.
上面写错了, 15M * 8 * 250= 30G.
这里的设计, 如果不用硬件ip 地址查找芯片, 那么必须让 250 个地址全部能被L2 cache cache 住, 否则根本就没戏.
而且这样设计的话, 还有一点很不好的, 250 个地址是需要预先知道的, 这样很不灵活. 但是如果根据包自动分析出下游子网的地址, 需要的数据结构就大了, l2 cache 放不下.
# redsea 发表于2006-07-30 15:23:00 IP: 222.50.36.*
我又搞错了, 不过这里不是我的原始分析数据, 我做正规分析的时候, 没有那么糟糕啊, myan 不要形成坏印象 ;)
10G 是 bps, 64 是 bytes,
# laoeyu 发表于2006-07-30 16:40:00 IP: 222.71.105.*
to redsea:
没错,CMT这种技术只是增加运算的带宽(Throughput),多核技术也是为了Throughput,它不能提高只有单个运算任务的事情。
至于超线程的技术我不清楚,不过它已被证明了,已经知道不少程序必须关掉超线程才能运行,而且现在许久没人提了,包括Intel。
至于你说的网络运用,10G的网卡问题,我想对现有的操作系统来说更是个挑战。千兆网卡对目前这种简单中断式Driver来说还可应付,但到了10G的网卡,这将会又是一个瓶颈。我想有必要下次blog里介绍Solaris是怎么解决的。
to sevencat:
“现在大家都习惯了模模糊糊、时断时续的网络视频,我相信5年以后我们一定会感叹自己当年的忍耐力。”
//==================================
这里面的瓶颈并不在CPU,而是在带宽限制住了。即使多核,他还是会这样。
我赞同,另一方面如我所说,多核对也只是增强了运算的带宽(Throughput),并不为了增强单个实际运算能力。
to myan
一直非常喜欢你的文章,希望能够看到更多准确和理性的文章。
就如何使用多核,我觉得有这三方面:
1. 使用现有的多线程模式去利用这种硬件。这个比较复杂,成本太高,毕竟让大家都用pthread, windows 多线程编程比较困难。
2. 使用一些高级的简易的模式去编程,比如一些第三方库,虚拟机比如java,天生就非常适合这种多core的运算,一个Java程序就含有多个线程,而且JVM可以动态的根据实际硬件进行动态优化。这个approach我觉得比较实际,但还需要等待这方面技术成熟起来。
3. 还有一种就是虚拟技术,利用一些技术或者就是简单运行,让一个应用跑多个实例,比如一个App Server,在一台机器上跑上多个实例:
具体可以参考www.spec.org的 Websphere + UltraSPARC T1 的数据,这可是目前SPECjAppServer2004 最高纪录。
Solaris + UltraSPARC T1 跑一个实例Websphere(1 Node), JOPS:615.64
http://www.spec.org/osg/jAppServer2004/results/res2005q4/jAppServer2004-20051108-00022.txt
在同一个系统下,Solaris + UltraSPARC T1 跑6个实例Websphere(6 Node), JOPS:
JOPS 3,328.80, 几乎就是原先的6倍。
http://www.spec.org/osg/jAppServer2004/results/res2005q4/jAppServer2004-20051122-00024.txt
由于大多数服务应用从设计上都只能运行一个实例(比如网口的绑定,配置文件的独享)这是就需要一些虚拟技术比如Zone。^_^
通过这种方式就可以轻松获得的由于使用这种Multi-Core的cpu带来的提升。当然这不一定是一个最好的方案,但对许多Legacy的系统来说,(往往面临原来做系统的人找不到了,或者运行商也不愿去更改这
# redsea 发表于2006-07-30 18:04:00 IP: 124.248.66.*
to laoeyu
我的这个应用, 用通用mpu 体系已经很难解决带宽的问题了, 专用 np 体系本身非常特别, 就不说了. 通用一些的计算机体系中, 好像也只有 numa 是可以解决这里的需求.
如果 PC 的发展, 带宽需求越来越强, 以后出现单硅片上的 numa 系统都不出奇, 毕竟现在的双通道内存这种技术扩充性并不好.
开发那个项目的话, 没有网卡的带宽问题, 实际上, 压根就没有网卡, 只有一个串行信号接口和物理层电路接口, 用这种 np 做一个网卡倒是没有问题. 网络接口本身是编程的重点对象了, 不是用一个 driver 去解决.
10 G 网卡 OS 的问题, 如果是在 tcpip 上面应用, 你可以search TOE 看看, tcp offload. windows 2003 解决得最好, linux 和 freebsd 还在追赶, 而且他们原来的ip 层功能太强, 要加上加速功能, 还要兼容原来的很强的iptables/ipfw 等功能, 我想并不是很容易.
# sevencat 发表于2006-07-30 11:53:00 IP: 203.156.209.*
N久以前多线程(哪怕是最早的多进程)的熟练和大规模的运用就开始了。
他们老早就是软件设计的热点了。
我的想法是:多核对操作系统内核的影响比较大(想想LINUX2.6,FB对多CPU的支持上面),但对普通开发人员来说,也许只要熟练运用多线程就可以很大程序上间接运用到了多核。
# sevencat 发表于2006-07-30 12:01:00 IP: 203.156.209.*
“现在大家都习惯了模模糊糊、时断时续的网络视频,我相信5年以后我们一定会感叹自己当年的忍耐力。”
//==================================
这里面的瓶颈并不在CPU,而是在带宽限制住了。即使多核,他还是会这样。
现在用得比较多的RM和MP4的解在当前主流单核CPU上是非常流畅的,不过MS有个什么高清对CPU要求非常高。
# sevencat 发表于2006-07-30 12:06:00 IP: 203.156.209.*
即使两三年之后这些应用真的很需要一些新的编程技术,我想到时候我再去学也不迟,而且计算机硬件和软件的发展都很迅速,两三年之后又会有哪些东东会出现,谁也不知道。
我觉得还是以需求推动,兼顾短时间之内可能会发生的变化。目前的需求没有让我一定要学习多核的必要(多线程倒是比较熟悉)。
# myan 发表于2006-07-30 12:45:00 IP: 219.236.55.*
to sevencat:
>> 但对普通开发人员来说,也许只要熟练运用多线程就可以很大程序上间接运用到了多核。
不是间接,是直接。对“普通”开发人员来说,只要熟练运用多线程就可保无虞,可以直接享受到多核优势。
问题在于,“普通”开发人员很少有“熟练运用多线程”的人。不信你打开一个多核机器上的Windows任务管理器,看看其中的两个CPU性能监视窗口,分别监控两个核的工作负荷。然后打开自己常用的软件,执行一些操作,你会看到,大部分的运算集中在一个核上。
Adobe最近得意的宣称他们的软件很早以前就充分考虑的多线程优化,他们为什么能要得意?这里还是有原因的。
# myan 发表于2006-07-30 22:03:00 IP: 219.236.55.*
to laoeyu:
谢谢你的精彩发言。关于网络视频,我当然知道现在的瓶颈是网络带宽,我的意思是说,一旦网络带宽增大,用户会要求高质量的视频服务。而一旦这个胃口被打开,那么会迅速地被吊高,很快就会到达这一点:CPU成为瓶颈。你可能还是会不同意,你会认为CPU永远不会是瓶颈,因为你可能看到过苹果iMac在20寸宽屏显示器上仅仅凭借单核Power芯片就能流畅播放H.264视频,你觉得那就已经足够了。没错,如果“视频服务”仅仅只是指满足我们的视听享受,那确实差不多够了。但我所谓“视频服务”远不是这个意思。高质量的实时视频是瓶子里的魔鬼,一旦被放出来,就会唤起人类的贪婪欲望,一大堆狂耗计算能量的应用将会出现,例如:危机监控和报警、实时身份识别、远程外科手术、远程教育、新类型的对战游戏,等等,只要你发挥你的想象力,这样的应用会很多。
当然,我们还可以告诉自己,没必要关心那么长远的事情。但我的看法是,第一,既然是讨论技术趋势,难道目光不应该长远一点吗?第二,这种事情未必很长远。事实上,我去年参与的一个项目,就遇到客户希望装摄像头监控工程裂缝的要求。
仅就这一点说说我的看法。你的其他观点我都非常赞成。
# myan 发表于2006-07-30 22:17:00 IP: 219.236.55.*
to redsea:
你把我都绕晕了,哪里还有工夫给你挑毛病 ;-)
你的这个应用确实比较极端,且看你如何解决。
# rr 发表于2006-07-31 08:45:00 IP: 60.191.25.*
我觉得不是多核无用,而是一般写程序的时候没必要考虑多核,适合用多线程的就用多线程,没必要的就单线程足以,让操作系统关心多核去吧。
# sevencat 发表于2006-07-31 08:57:00 IP: 203.156.209.*
的确,多线程比较难用,有不少游戏的逻辑服务器为了省掉很多麻烦的东东,就在处理中用一个线程跑。
像那种像web服务的很容易利用多进程、多线程来提高速度,但像有些地方利用多线程增加了很多逻辑复杂性,会发现N多的东东要锁定。
pthread,_beginthreadex的API(还有附带的pthread_mutex,CriticalSection之类的锁)比较简单,但跟程序的逻辑结合在一起,有时候就相当复杂了,要考虑的东东多了不少。
# jamesandy 发表于2006-07-31 09:15:00 IP: 218.17.37.*
多核和我这样的应用程序开发者没有多大关系吧?也和大多数的web开发者没有多大关系?
说得干脆点,多核和基本99%的程序员没有关系。
想想3d游戏开发者需要关心显卡是什么GPU的么?
他们只需要调用directX的最新接口就行了。
同样,我们开发的程序最后也不用关心什么多核,单核。
什么“从现在算起,2-3年之内,多核程序设计(其实就是多线程程序设计)将成为软件开发领域的热门主题” 纯粹胡说八道。
# jamesandy 发表于2006-07-31 09:22:00 IP: 218.17.37.*
“多核程序设计(其实就是多线程程序设计)”
我实在汗一把什么,这是什么跟什么啊!
基本概念都搞错了!
“多核程序设计”和“多线程程序设计”根本是两码事!
”多核程序设计“的根本是让一条线程在多个cpu上同时运行!
而”多线程程序设计“的根本是一个cpu上运行多个线程!
或许我也说错了,但总比没有说得要好,就算科普吧
# tangl_99 发表于2006-07-31 09:27:00 IP: 218.88.37.*
web开发是最低级的开发应用。中学生都会。的确没有必要涉及到多线程,并行计算方面的。
# sevencat 发表于2006-07-31 09:44:00 IP: 203.156.209.*
实在无法认同web开发是最低级的开发应用....
我建议删除该评论。
# 李嘉 发表于2006-07-31 09:52:00 IP: 124.203.147.*
多核肯定是有用
我自己用 单核现在就不够了
不过多线程未必就会流行
一来多线程编程确实比较麻烦
二来线程多的时候性能未必好
我觉得在双核的时代多进程可能会比较比较流行
一来现有的代码不用太多改
二来把分配的事情交给OS比较放心
这样的话 诸如进程间通讯的技术就要多看看了
一般的程序 都有数据存取模块 将这样的模块用 OLEDB 等技术封装 使数据功能分开到两个进程 这是我目前在做的工作
# redsea 发表于2006-07-31 10:36:00 IP: 61.144.96.*
>你的这个应用确实比较极端,且看你如何解决。
很简单, 这个不是我的主业, 只是试图创收, 周期太长,要学习的新东西太多, 我就会放弃, 呵呵.
结果, 我评价用单一通用体系like 的network procesor实现这个东西是不可行的.
我觉得可行的方案包括, 特定于应用方案的network processor; 可以扩展互联的network processor; 通用cpu 体系like 的 network processor 之间用高速通信接口连接, 多级多cpu 解决这个问题.
# phoenixsh 发表于2006-07-31 11:13:00 IP: 222.67.6.*
讲到未来的多媒体应用,现有的x86根本就是不能够胜任的,即使使用多个核也不见得好到哪里去。孟岩提到的“危机监控和报警、实时身份识别、远程外科手术、远程教育、新类型的对战游戏”之类的应用,如果能够解决网络带宽瓶颈的话,下一个瓶颈也未必就是CPU的计算能力,而更有可能是内存带宽的限制。而且,多媒体应用是流式的,提高缓存容量没有多大意义。这些应用也有一些要在嵌入式设备上运行,对于功耗有严格的要求。这些问题的解决,需要更好的处理器架构。x86已经差不多到头了,连XBOX360都抛弃x86了,PS2/PS3就更不用说了。如果内存带宽连一个核都满足不了,增加更多的核的意义何在呢?估计也就是在一些内存带宽要求不高而计算能力要求非常高的场合适用,可惜多媒体应用是非常消耗内存带宽的。
伯克利大学有一个很有意思的项目,是专门研究研究如何消除内存带宽瓶颈的:
http://iram.cs.berkeley.edu
本人最近也在学习,作了一些笔记:
http://blog.csdn.net/phoenixsh/archive/2006/07/23/964945.aspx
to jamesandy:
>”多核程序设计“的根本是让一条线程在多个cpu上同时运行!
一个线程怎么可能在多个CPU上同时运行??您还是弄清楚了再来科普别人的好。
# redsea 发表于2006-07-31 11:01:00 IP: 61.144.96.*
to jamesandy
>”多核程序设计“的根本是让一条线程在多个cpu上同时运行!
而”多线程程序设计“的根本是一个cpu上运行多个线程!
>让一条线程在多个cpu上同时运行!
这个技术还没有出来吧?
多核计算和多线程计算是有一些区别的. 多线程计算的时候, 你不知道是否有多个物理cpu, 做多核计算的时候, 肯定知道已经有多个物理 cpu 了.
似乎现在 intel 一个多核上一个重点技术是 openmp 吧? 如果是这样就容易理解了, oepnmp 是让程序员不必亲自动手写进程间的数据共享,锁定同步代码, 而让程序中的一些可以并行计算的代码块多cpu 进行计算.
openmp实现上还是多cpu 跑多线程的. 不过和传统的多线程编程方式有所不同, 这主要针对计算任务, 同步锁定问题较简单, 不过需要仔细分析出可并行计算的代码块来.
# 非典型秃子 发表于2006-07-31 13:21:00 IP: 202.95.81.*
多核时代只是多线程的硬件支持吗?那和多CPU比起来,除了提高集成度,优势又在哪里呢?
另外,并行计算一直不是主流,这一支力量已经蠢蠢欲动了,大有可能借多核的东风成为技术宠儿。
# dreamhead 发表于2006-07-31 12:21:00 IP: 219.232.60.*
多核的用途和未来无庸置疑,但是myan的讨论中混淆了一些概念,多核带来的问题并不在多线程上,而在于并行上。
我们更熟悉的例子是那些在服务器上使用的多线程技术,也就是任务并行,任务并行大多是在一个线程里完成一个完整的处理,线程之间的协作和交互并不多。多核的到来,需要我们在更细的层次上去考虑多线程,比如在多媒体解码、矩阵运算等,这时候,我们需要的是在一个任务中的并行。在程序员们原来的工具箱中,对并行计算考虑得甚少,因为通常用不到,所以,才会出现myan在留言中举例的CPU计算集中在一个核上的现象。这不是学习了多线程编程就能够解决的问题,更重要的是学会如何进行并行处理,否则,就会成了穿新鞋走老路。
Java之父在这个问题上理解也存在偏差,看看这篇blog的留言:
http://blogs.sun.com/roller/page/jag?anchor=mpi_meets_multicore
# sevencat 发表于2006-07-31 12:30:00 IP: 203.156.209.*
to:dreamhead
能否具体讲一下多媒体解码中对多核的运用?
多核除了多线程,我们怎么利用他?
# dreamhead 发表于2006-07-31 12:37:00 IP: 219.232.60.*
再说两句,从我的观察来看,多线程编程在多核问题上并不像文章里提到那么重要.
程序设计的一个发展方向是简化,像Java让人们忽略了内存问题一样。正如我在上一个回复中说到的,多核的问题在于并行。所以,现在已经有人在探索简化并行编程了,OpenMP就是在这个方向上探索比较成功的例子,我们使用OpenMP进行编程的话,好的并行程序几乎多线程的存在,当然与算法设计与实现密切相关。据我所知,现在已经有不少类似的探索,目的就是让程序员忽略复杂而易错的问题。当然,这条路不是一时半会就可以到达终点的。不过,这条路确实有着美好的前景,一旦探索成功,那种只待CPU升级的日子又会回到程序员身边,不过,那时等待的是增加更多的核,而不是曾经的CPU频率。
当然,在那一天到来之前,我们还是需要掌握多线程技术的。:)
# sevencat 发表于2006-07-31 12:40:00 IP: 203.156.209.*
谁能告诉我OpenMp在intel平台上的并行的实现原理,是用多线程,还是用汇编对多核进行直接操作怎么的?
并行?多线程不也是一种并行吗?
# phoenixsh 发表于2006-07-31 15:40:00 IP: 222.67.6.*
to 路过:当然,无可否认,pipeline编程模式用在多核处理器上是很自然而且也很高效的。我的理解是,pipeline编程模式仍然要架构在多线程之上,直观上类似于工厂里面的流水线:每个线程只处理一部分任务,好比这个工人只拧某一颗螺丝;也许存在不使用多线程的实现,不过我很难想象出来。我的问题是,你说的*同时*在这里究竟意味着什么呢?
# TripleX 发表于2006-07-31 16:13:00 IP: 222.128.6.*
做内容分析 还是得用些专用的芯片 比如加一些CAM什么的 用CPU跑 内存带宽怎么的都不够的 或者就用更老土的办法 用一个load balance设备把一个10G分成10个1G 在10个cpu上分析 load balance设备只做分发 用NP做正合适 后面的内容匹配可以用x86 CPU
# csdn 发表于2006-07-31 16:43:00 IP: 218.80.101.*
to phoenixsh
同时是不是可以这样理解:
比如sum = (a*b)+(c*d);,(a*b)和(c*d)是可以同时运行的,
并不是一定要先运行a*b,然后把运算结果移到内存,然后计算c*d,再与上次计算结果相加
# phoenixsh 发表于2006-07-31 17:12:00 IP: 222.67.6.*
to csdn:
没错,你说的是并行计算。在这里,a*b和c*d的计算次序并不重要,在哪里计算的也无关紧要。我必须承认,“同时”具有双重含义:有物理意义上的,有逻辑意义上的。你这里的例子是逻辑上的同时(也有可能碰巧物理上同时发生)。单核处理器上不存在严格物理意义上的同时(不讨论超线程),只有逻辑同时。我在前面的回复中假设“同时”解释为物理意义。
如果我们仍然承认线程就是处理器上指令的逻辑序列,那么我仍然认为,在多核处理器上,不存在一个线程能够物理同时地在多个核心上执行。
也许是我错了,请高手指正。我是认真的,我对并行计算和多核架构也只是门外汉而已。期待高手开新贴详细讲解多核架构的编程模式,和/或者介绍OpenMP的原理。
# 风雷 发表于2006-07-31 11:52:00 IP: 222.208.208.*
phoenixsh 过虑了,intel和amd似乎还没有差到连内存带宽都发展不起来的地步。目前的HT3.0和CSI都着眼于内存带宽的解决,系统总线只要不成问题,内存本身的带宽是丝毫不用担心的。
当内存这块解决后,网络带宽一跟上,cpu自然也就成了下一个解决点。且不说现在的core 2已经抛弃了传统的x86架构,parrot也是蓄势待发。
所以不要对硬件过于担心,除了硬盘,基本上软件、游戏有需求的,硬件的发展都能满足。多少新技术已经完全成熟就等待上马了
# 光影传说 发表于2006-07-31 19:03:00 IP: 58.33.73.*
只要涉及到服务器端程序,没有不考虑到多线程的。
考虑到多线程,肯定要考虑到多核、多服务器
对于服务器端的软件,硬件的资源总是不够用。
# littleroy 发表于2006-07-31 19:19:00 IP: 221.207.250.*
to jamesandy
目前单核的cpu而言,确实是多个线程在单cpu运行,而多核cpu就可以在逻辑上,可以多个线程在多个cpu上运行
to phoenixsh
单个“逻辑“线程,我个人觉得可以在多个“逻辑“的cpu上运行,用openmp目的就是这个,
我个人觉得你们讨论的不是一个层次的东西,有点各说各话,
to myan
程序员在使用多线程编程的时候,应该注意几点(从intel的官方文档看来的:)):
1: 使用线程池
2:活动线程不要太多(一半等于cpu的个数)
3:使用粗糙划分的线程,而不是细微划分的线程
4:最小化实施同步
5:不要使用错误共享缓存
openmp是针对以后代码的的细微划分的线程工具,
而一般多线程属于粗糙划分工具
个人觉得,在设计程序的时候,,首先考虑的不是使用openmp去并行编程,而是,使用线程池去粗糙划分,最后才使用openmp去微调程序, 个人意见,仅供参考
# littleroy 发表于2006-07-31 18:42:00 IP: 221.207.250.*
to myan
孟先生的文章预测了产业的发展方向,我个人比较认可
从上层而言:
多线程确实直接利用了多核的好处,
但从底层而言,好的编译器,确实也可以将单线程的指令放到多核去执行,比如intel的最新的编译器。
所以,到了若干年以后,不使用多线程编程,或者不懂多线程技术的程序员,确实可以利用多核的好处,就像从dos迁移到windows一样,不懂消息机制的程序员,利用delphi做出非常漂亮的windows消息的程序,
但是,如何精通多线程通讯和多核程序的设计原理,也会让程序员身价倍增!
所以,个人意见:在程序中,尽可能把程序做成多线程或者多进程都直接利用了多核的好处
# littleory 发表于2006-07-31 20:51:00 IP: 221.207.250.*
to servercat
servercat兄弟,现在还在腾讯混咋样了,:)
从“传统的逻辑上“说的单线程,比如windows下,是用createthread函数创建的线程,
但是,如果考虑并行编程的话,比如使用openmp等工具优化的程序
一个所谓的“传统的逻辑上“单线程,会被编译器和操作系统的合力下变成了多线程在多核上进行平行计算,所以,从这个角度说,单线程就可以在多cpu上运行了,
这有点像指令级的概念平移上线程上来了,,,:)
# sevencat 发表于2006-07-31 20:05:00 IP: 203.156.209.*
虽然多线程能在多CPU中运行,但我看到书上说的是一个线程一个时候只能在一个CPU上运行,而且一般是每个CPU有一个任务队列和迁移队列,一般来说线程不会随意从一个CPU的任务队列迁移到另外一个CPU中去,WIN下要是一个程序设置了CPU亲缘度的话,就更加少了。LINUX2.4倒是多CPU共享一个任务队列的。
# redsea 发表于2006-07-31 22:26:00 IP: 61.144.96.*
>一个所谓的“传统的逻辑上“单线程,会被编译器和操作系统的合力下变成了多线程在多核上进行平行计算,所以,从这个角度说,单线程就可以在多cpu上运行了,
但这实际上是先标识出准备进行并行计算的代码块, 编译器在此生成多线程并发计算代码. 实际运算过程中, 执行到此的时候, 从线程池中取出相应数量的线程, 并行处理此代码块.
在多物理核的情况下, 多个线程自然映射到了多个cpu 了. 如果预先设定的并发度高于物理 cpu 数, 这里反而有反效果.
这是对程序员而言, 看不到多线程调度, 但是 os 一层仍然是多线程.
os 一层, 一个线程可以被多个物理 cpu 执行目前的技术水平应该是做不到的, 即使能够做到, 那么直接认为是做出了一个更加强大的单 cpu, 概念岂不是更加清晰 ? ---- 类似x86指令分解之后, 微指令乱序执行, 并发执行, 已经象这样了.
# phoenixsh 发表于2006-07-31 22:48:00 IP: 218.82.51.*
to littleory:
你的解释的确能够自圆其说,我无话可说。
在CELL处理器上有一种编程模式叫做流模式,由PPE做控制器,各个SPE依次计算经过自己的数据流,不知道跟前面说的pipeline模式有何异同,感觉很像的说。
关于你提到的“榕木通讯库”,不知道是不是霍尔的“Communicating Sequential Processes”理论的一个应用?好奇的问。
另外,你给的项目地址似乎不能访问哦。
# datuhao 发表于2006-08-01 00:03:00 IP: 219.136.78.*
多核不是无用,而是多核的应用范围有限,过去是这样,今后也不会有太大改变,就算以后每台PC上都被"强制"安装双核.
你的应用领域决定了你是否需要多核.
应用需要的话,多少个核都不够用,像那种低速的输入也会引起高强度的计算的应用,根本瓶颈就在cpu,多核在这种情况下可以很好的提高单个节点的计算能力.
相反如果应用领域有限制话,就算是一个古董级的单核cpu你也不允许占用太多,像大多数的企业应用,网络客户端程序等等.还有就是像那种逻辑上不存在并发的,就是说那种必须严格按序列执行的的程序,多核同样无能为力.
就是说应用领域决定了cpu是短板还是长板,是短板的地方,提供再多核他也是短板,是长板的地方,你玩命提高网络和内存的I/O速度他也还是长板. 所以说,在大多数领域,多核没有太大的意义,而在少数适用领域,多核同样不存在革命性意义.
是因为应用需要,才会用到多核,而不是因为多核存在(或是以后Intel只卖多核了),我们开发就必须开多线程去榨cpu性能(即使你榨不出来:).
# datuhao 发表于2006-08-01 00:10:00 IP: 219.136.78.*
多核不是无用,而是多核的应用范围有限,过去是这样,今后也不会有太大改变,就算以后每台PC上都被"强制"安装双核.
你的应用领域决定了你是否需要多核.
应用需要的话,多少个核都不够用,像那种低速的输入也会引起高强度的计算的应用,根本瓶颈就在cpu,多核在这种情况下可以很好的提高单个节点的计算能力.
相反如果应用领域有限制话,就算是一个古董级的单核cpu你也不允许占用太多,像大多数的企业应用,网络客户端程序等等.还有就是像那种逻辑上不存在并发的,就是说那种必须严格按序列执行的的程序,多核同样无能为力.
就是说应用领域决定了cpu是短板还是长板,是短板的地方,提供再多核他也是短板,是长板的地方,你玩命提高网络和内存的I/O速度他也还是长板. 所以说,在大多数领域,多核没有太大的意义,而在少数适用领域,多核同样不存在革命性意义.
是因为应用需要,才会用到多核,而不是因为多核存在(或是以后Intel只卖多核了),我们开发就必须开多线程去榨cpu性能(即使你榨不出来:).
# datuhao 发表于2006-08-01 00:17:00 IP: 219.136.78.*
不小心多刷了一下,孟老师删了吧.
其实多核也不是什么新鲜玩意,说白了就是两个cpu合到一起,少占了地方而已,以前多cpu下怎么写多线程在多核上就怎么写.
# littleory 发表于2006-08-01 01:32:00 IP: 221.207.250.*
to redsea
"os 一层, 一个线程可以被多个物理 cpu 执行目前的技术水平应该是做不到的"
请问这里的“线程”是指什么?因为讨论到多核的时候,线程的概念会有两个层次
使用OpenMP API,程序员可以把代码块切割成几个线程在运行
程序员可以使用omp parallel pragma在OpenMP中创建线程。例如,下面的代码展示了如何创建一个三线程的并行区域:
float array[N];
int ID;
//function requests 3 threads
omp_set_num_threads(3);
#pragma omp parallel
{
//function returns thread ID
ID = omp_get_thread_num();
div_func(array, ID);
}
printf("Done.\n");
每个线程将都将执行结构化块内的代码,最后,每个线程将冗余地调用div_func(array,ID)其中ID=0到2所有的线程都共享一份数组变量,并将在打印语句(障碍)之前重新集合。
以上文档请看intel官方文档
to phoenixsh
网址是这个
http://gforge.osdn.net.cn/projects/royfilesocket/
这个东东没有你想的那样,
而仅仅是用临时文件来做进程间通讯,或者进程中线程间通讯的库而已,
我认为它可以方便开发者使用多线程编程,随便也可以迎合多核时代,,
# lixeon 发表于2006-07-31 18:06:00 IP: 60.176.177.*
从现在算起,2-3年之内,多核程序设计(其实就是多线程程序设计)将成为软件开发领域的热门主题。
但三年之后,程序设计则无需考虑是否多核,因为肯定有平台、工具为我们了做了这些,一般程序员又不需要知道什么多线程设计了,只需要拿一些库来拖拖就行了。
# nokidding 发表于2006-08-01 00:19:00 IP: 219.135.147.*
唱些反调
1 多核其实是芯片厂商碰到了速度的极限后推出的又一个卖点而已
2 对一台电脑同时运行多个系统有好处
3 多线程和多核其实没有什么关系
4 多核编程主要是操作系统和编译工具的作者研究的东西
5 普通应用程序的作者没有必要欣喜若狂
6 No silver bullet
# YCL 发表于2006-08-01 12:51:00 IP: 211.95.116.*
不知从哪里看到过一个报道,包括intel在内正在研究一种“反多线程”技术,让多核的CPU在程序面前变成“单核”,开发者不用考虑多核,这个技术把你的程序分布到多个核上执行。
# bluecoff 发表于2006-08-01 13:42:00 IP: 221.234.220.*
很赞同sevencat的观点,多核当然是未来趋势,但主要是做操作系统和编译器等的系统开发人员受到影响,对普通应用开发而言应该是透明的,影响不可能有多大,否则就是历史的倒退,倒退到要求普通应用开发也要关注硬件细节的年代.
# littleory 发表于2006-08-01 19:37:00 IP: 221.207.250.*
YCL,你看的报道是真的,这个技术据说可以让一个线程在多核上同时运行,
不过这些都是纸上谈兵,那位同志确实用openmp来进行并发编写程序?
获得实实在在的好处?
# 云风 发表于2006-08-01 18:55:00 IP: 218.72.95.*
redsea, 我的感觉是,你的应用固然通过计算,发现内存带宽不够了。但是不能说明 CPU 的计算能力就够。
单从处理正则表达式这个任务来说,个人感觉,处理一个正则表达式的任务,通常在 cpu 达到满负荷的时候,内存带宽应该还在闲置。
你现在的问题如果是为了解决内存带宽不足的问题,比如处理 10G 光纤上的数据包的问题,我想可以通过增加处理用机器个数的方法。把处理数据用的机器并在光纤上,设计某种算法,可以截取光纤上的一部分数据流分析,而不需要将所有数据都通过内存。降低单台机器的数据量的负荷后,我想下一个面临的问题依旧是 CPU 的处理能力。
我个人的经验是,内存的带宽形成的瓶颈被认为夸大的可能性极大。一般来说,让内存带宽形成的瓶颈大于 cpu 的运算能力,cpu 做的事情就不比 memcpy 复杂多少了。而纯粹的数据复制大多可以利用改进方法来避免。
# redsea 发表于2006-08-01 21:46:00 IP: 61.144.96.*
to 云风
在这个案例里面, 内存带宽不够未必cpu 能力就不够的.因为只要一个tcp/udp 连接被成功分类出来之后, 后面的数据流就不必分析, 分析处理就简单了. 当然 ftp, h323 控制连接之类的要继续分析, 不过这些的数据量并不大.
如果内存带宽够,cpu 能力不够, 那么正则表达式分析之类的任务,采用硬件加速引擎可以减轻cpu 负荷.
这个案例里面, 所有参与的机器必须能够访问到相同的分类和统计数据结构, 如果单一机器带宽不够, 那么必须用类似 numa 结构(硬件方案)或者 cluster 结构(软件方案)来处理. 倒也不是从技术角度无法完成, 只是需要的投入比预期的大,从风险和投资回报的角度来看, 不是很值得了, 本来就是为了解决主业收入的尝试.
# lyx 发表于2006-08-01 23:05:00 IP: 220.171.233.*
在科学计算领域,多核的应用早就很普遍了。intel现在把它带到PC领域了。OpenMP个人认为是一种学习代价比较低,而且代码的简洁性较好的并行计算的方案。
曾经听过一个讲座,说OpenMP当处理器个数超过一定限度后(大概几十个),边际收益递减的比较厉害,MPI要好得多。不过MPI学习代价和编程时的难度要大多了。
# 云风 发表于2006-08-01 19:01:00 IP: 218.72.95.*
to littleory:
即使使用 openMP, 并发用的线程依旧依赖操作系统的调度和管理。openMP 并不是编译器从 CPU 那里获得的额外的恩赐。
# laoeyu 发表于2006-08-01 23:24:00 IP: 222.71.103.*
to myan
谢谢,知道了。好高兴看到你的回应和留言。
几天不来就有那么多的留言,这个topic好热啊。
# 云风 发表于2006-08-01 19:03:00 IP: 218.72.95.*
to littleory:
即使使用 openMP, 并发用的线程依旧依赖操作系统的调度和管理。openMP 并不是编译器从 CPU 那里获得的额外的恩赐。
# TripleX 发表于2006-08-02 01:53:00 IP: 61.51.143.*
to littleory:
所谓的线程我想应该是指运行的上下文 要同时在两个CPU上跑 至少得有两套上下文 也就是说两个线程 两个CPU上运行的代码看到的栈状态是不同的 而且即使是双核 两个核也是不能互相访问寄存器的 只是共享内存 所谓的线程上下文 无非就是寄存器和栈 两个core的寄存器和栈都不同 当然就是在跑两个不同的线程 YCL说的技术是双核变单核 而不是一个线程跑在两个核上 我猜想应该是这样的 比如原来每个核有8个寄存器 那么切换成单核以后就会有16个寄存器 八个是可名名访问的 另外八个做shadow 执行单元可以同时执行的不冲突指令也可以增加 当然效果不会是x2那么好的 估计也就是如果双核的时候算两个P2 单核的时候能算一个同频的P3这样子 对付单线程密集运算 也只能这样了
呵呵 睡不着觉 再胡说几句 双核和原来的双CPU比(x86架构) L2 cache是共享的 这样线程在两个CPU之间迁移的成本降低很多 内存带宽的压力也减轻 其它的体系结构里的多核 有不少比x86要变态 比如可以把L2 cache分一部分出来做可寻址的高速内存 在很多极端情形下能优化得更好 硬件领域里古怪的东西很多 针对很多特殊的应用的 x86 dual core主要还是针对pc了
dual core对pc挺有用的 至少某个程序大量消耗CPU的时候不会搞得别的程序响应慢下来 原来用preemptable kernel补丁的时候感觉已经不错了 现在发现 双核更好 如果能有一个实时性更好的IO调度器就更好了
OpenMP MPI这样为大规模并行计算的东西 一直都很重要 在未来 不见得会更重要 我们可以制造8 core的cpu 然后每16个装在一台机器里 焊上128M L3 cache 机器之间用Infiniband连接在一起 可以应付紧耦合的并行计算 或者是象seti@home那样用无数的用低带宽网络连接的pc做松耦合的运算 但是那些不是大多数应用开发者在玩的东西 大部分人以前在用SMP的机器 现在改dual core了 其实差不太多 multi-core不是今天才有 Power上早就有 最近才卖到百来美金一片倒是真的 拿以前的MMX指令来说 是有不少用 但是机器也不见得就飞起来 不看片的时候 是没什么用的 dual-core也一样 不像提升频率那样会对所有事情都有帮助
每次有这种新技术推出 搞开发的都乐坏了 甭管怎么样 有新东西玩了
# 石头 发表于2006-08-02 10:18:00 IP: 218.247.0.*
myan的文章着实不错,看来这里也有很多多核技术方面的高手,论坛中有专门一块版块是讨论多核技术的,大家也可以去那里与其他人交流多核技术,作为版主,myan也在那里发表了很多好的观点,有兴趣的朋友可以去看看。http://community.csdn.net/Expert/ForumList.asp?typenum=1&roomid=609
# myan 发表于2006-08-02 00:21:00 IP: 219.236.51.*
to lyx:
据我所知,MPI主要处理多计算机,而OpenMP主要处理共享内存的的多CPU单计算机。两者还是有一定查别的。
我有一个朋友也认为OpenMP这种对共享资源加锁同步的路子走不了多远,超级并行需要类似MPI的思路。这方面大概会是未来一个重要的发展方向,也许未来的并行软件会用像Erlang那样的语言来开发。
# lyx 发表于2006-08-02 10:29:00 IP: 61.189.157.*
OpenMP以线程为单位,MPI以进程为单位,所以MPI可以多机并行,但是在一个机器上也是可以跑的。前几天去广西出差,接触一些搞遥感的,他们之前的程序都是单线程的,而且程序开发了好几年了,我建议他们用OpenMP来提高计算速度。遥感领域,很多时候,算法并不一定很复杂,但是数据的分辨率太高了,数据文件通常都很大,如果再做几个月、一年的统计分析,耗时很多。而且热点代码段就是那几个for循环,简单的加一些OpenMP的编译指令,就可以很明显的提高速度。
感觉OpenMP有个很明显的优点,1、改造现有代码,使之并行化时,代价不高。2、学习难度较小。通常需要做大规模科学计算的人,都不是计算机专业出身,而是物理、生物、化学之类的,虽然再性能提升上,OpenMP有它的局限性,但是从应用角度来讲,有它的实用性。我曾经见过一个非计算机专业的人,笑呵呵的说,还是OpenMP这种技术,简单好用。
# 云风 发表于2006-08-02 13:29:00 IP: 218.72.95.*
to redsea, 我的意思就是如此。之所以导致内存带宽成为瓶颈,是因为你的 cpu 做了大量无意义的 memcpy。"tcp/udp 连接被成功分类出来之后, 后面的数据流就不必分析, 分析处理就简单了" 就是佐证之一。不需分析的数据流,流过了内存。
我们应该想办法让这个数据流不流过内存,而不应该简单的归咎于内存带宽不够。这比利用额外的硬件去处理正则表达式分析之类的任务要廉价的多。这就像先迫使采用更先进的硬件技术,解决内存带宽问题,然后再给 cpu 打补丁跟上超出的内存带宽部分。
相比较而言,我感觉,去掉"所有参与的机器必须能够访问到相同的分类和统计数据结构" 这个条件的解决方案会相对廉价。
即使这个问题很难解决,在内存上做些手脚也比加一个处理正则表达式的硬件要方便。比如解决内存到显示设备的带宽问题的 AGP 技术。它可以存在的原因就是大量显示数据许多并不需要 cpu 来运算处理。
ps. 有个问题我不明白,网卡上来的数据不可以收到后立刻处理或丢弃吗?必须进入内存?只在 L1 cache 上打转转,带宽是够的吧?
# 云风 发表于2006-08-02 13:37:00 IP: 218.72.95.*
to redsea, 我的意思就是如此。之所以导致内存带宽成为瓶颈,是因为你的 cpu 做了大量无意义的 memcpy。"tcp/udp 连接被成功分类出来之后, 后面的数据流就不必分析, 分析处理就简单了" 就是佐证之一。不需分析的数据流,流过了内存。
我们应该想办法让这个数据流不流过内存,而不应该简单的归咎于内存带宽不够。这比利用额外的硬件去处理正则表达式分析之类的任务要廉价的多。这就像先迫使采用更先进的硬件技术,解决内存带宽问题,然后再给 cpu 打补丁跟上超出的内存带宽部分。
相比较而言,我感觉,去掉"所有参与的机器必须能够访问到相同的分类和统计数据结构" 这个条件的解决方案会相对廉价。
即使这个问题很难解决,在内存上做些手脚也比加一个处理正则表达式的硬件要方便。比如解决内存到显示设备的带宽问题的 AGP 技术。它可以存在的原因就是大量显示数据许多并不需要 cpu 来运算处理。
ps. 有个问题我不明白,网卡上来的数据不可以收到后立刻处理或丢弃吗?必须进入内存?只在 L1 cache 上打转转,带宽是够的吧?
# TripleX 发表于2006-08-02 15:29:00 IP: 222.128.6.*
to 云风
现在的一半pc上的网卡都是通过DMA接收和发送数据的 接收数据的时候 OS分配一个buffer 然后把buffer指针的首地址(总线地址)写到网卡的某个控制寄存器里 网卡收到包的时候直接写内存 写完以后发一个中断通知OS 发包过程类似
OS在中断处理里处理数据包 需要重新把包的一些部分加载到L1 cache
基于polling的系统可以减少中断的开销 但是还是要读写内存的 一些10G网卡上集成处理tcp的加速引擎 但是内容匹配和过滤是不带的 都只能用cpu处理 而网卡和cpu之间的媒介就是内存
# TripleX 发表于2006-08-02 15:31:00 IP: 222.128.6.*
to 云风
现在的一半pc上的网卡都是通过DMA接收和发送数据的 接收数据的时候 OS分配一个buffer 然后把buffer指针的首地址(总线地址)写到网卡的某个控制寄存器里 网卡收到包的时候直接写内存 写完以后发一个中断通知OS 发包过程类似
OS在中断处理里处理数据包 需要重新把包的一些部分加载到L1 cache
基于polling的系统可以减少中断的开销 但是还是要读写内存的 一些10G网卡上集成处理tcp的加速引擎 但是内容匹配和过滤是不带的 都只能用cpu处理 而网卡和cpu之间的媒介就是内存
# 云风 发表于2006-08-02 22:54:00 IP: 218.72.95.*
如果网卡是通过 DMA 把数据写到内存,那么就不存在内存带宽受限的问题了。因为这一步并没有占用带宽。这跟 redsea 先前的估算有出入。
我的观点只是,只要确认 cpu 本身没有做大量的 memcpy 操作,甚至 cpu 都要做正则表达式匹配这种工作了,内存带宽问题取代 cpu 速度问题造成瓶颈的可能性是非常的小的。即使有内存带宽问题,也大多可以从改善 cache 利用这方面来解决。
当然,我个人觉得最好还是想办法把任务分担到多台机器上,这样,每台机器的 CPU 也可以做更繁重的工作。
# TripleX 发表于2006-08-02 22:59:00 IP: 222.128.6.*
DMA也要写内存阿 路径是 网卡->PCI总线控制器->内存控制器->内存 如果这时候CPU也要做内存操作 是会halt的
# TripleX 发表于2006-08-02 23:10:00 IP: 222.128.6.*
而且他们搞IDS/IPS的 特征库都超级大 我认识一个在fortigate工作的家伙 他说他们的库加载以后消耗1G内存 想完全靠cache是很困难的 ...... 就算有很好的算法 匹配过程中也会有多次cache miss
# redsea 发表于2006-08-02 23:10:00 IP: 61.144.96.*
to 云风 如果网卡是通过 DMA 把数据写到内存,那么就不存在内存带宽受限的问题了。因为这一步并没有占用带宽。这跟 redsea 先前的估算有出入.
TripleX 的说法是对的. 并不是只有cpu 访问内存才占用内存带宽. 只要有内存访问, 包括 CPU 访问, DMA(bus master), 或者集成显卡的访问主存, 或者 AGP 访问主存, 都是要占用内存的带宽的.
而且内存的带宽是比较有限的, 技术进步也不是很快的.
特别是, 连续访问时候的吞吐量提高得还快些, 随机访问从内存芯片得到地址信号, 到首个数据开始输出的lagacy 这个参数, 从fpram, sdram, ddr, ddr2 几代内存来看, 进步比连续带宽的进步还慢.
例如, DDR 到 DDR2, 是连续访问的吞吐量大了, 但是首次访问一个非连续地址时候, 需要经过一个 legacy 时间才能获得首个输出, 在这点上, DDR2 和一半频率的 DDR 的延迟是一样的 (DDR2 800 的这个值, 和 DDR 400 一样.)
在这点上, 内存和硬盘实际上一定程度上类似, 对代码有些什么影响也可以类比.
BTW: 还有, 当前的 cpu 设计, cpu cache 内部的值才是 trusted 的, 内存里面的值是 dirty 的.
# TripleX 发表于2006-08-03 00:39:00 IP: 222.128.6.*
在x86上 内存和cache的同步是自动的 就是说如果网卡通过DMA方式写了一段内存 cpu会收到内存控制器的信号 将对应的cache line设置成失效 但是在很多RISC芯片上不是这样的 需要用专门的指令去让cache失效 然后去读这段内存的时候cpu才会去内存里重新取值
linux里的pci_dma_sync_single_for_cpu在不同体系结构里的实现就能看出来 很有意思
# 云风 发表于2006-08-04 14:03:00 IP: 218.72.95.*
是我的理解错误,我误解了内存带宽一词。
内存带宽的概念,在我的概念中其实是内存的吞吐量。
# 路过 发表于2006-07-31 14:13:00 IP: 58.60.63.*
to redsea.
让一条线程在多个cpu上同时运行, 是指pipeline的编程方式, 一个应用的多块在不同cpu上计算, 提高cpu的缓存利用率, 与多线程编程差距很大的.
# dreamhead 发表于2006-07-31 14:13:00 IP:
To seventcat:
目前为止,我知道可用的利用多核的方法也只是多线程。并行和多线程是两个不同层次上的问题。其实,多线程和并行并不矛盾,并行可以通过多线程来实现,但并行的覆盖面比多线程更加广泛,比如,我们可以利用多机来实现并行。
据我的了解,OpenMP是以多线程来实现的,采用fork-join模型,简单说来,就是在需要并行的地方创建线程,将可以并行的任务交给不同的线程处理,等到处理完之后,再汇总到主线程继续向下走。这是OpenMP中比较基本的概念,去翻翻资料就知道了。我觉得OpenMP的好处在于简化了并行编程的复杂度。
To 非典型秃子:
当你掏钱买CPU的时候,你就知道多核比多CPU的优势在哪了。:)
# DSharp 发表于2006-08-06 09:40:00 IP: 221.0.182.*
说多核无用的人就是幼稚的表现,和幼稚的小P孩没有什么好争的时间会证明一切,就现在的这点计算机软硬件水平,跟科幻小说里的未来相比,简直就是个算盘。
计算机出现到现在,不过是五,六十年的事情,简直连初级阶段都算不上。发展的空间长远着呐。
以我的大胆预测,五年之后,8-16核心的CPU将会大量使用,一般机器都会配置10G的内存,现在的笔记本电脑将全逐步替代台式机成为常用配置,而工作出差的电脑,将被现在的类PDA设备取代。
微软将会推出Windows2010,这将会是一个真正的多任务操作系统。PC机上的操作和互联网上的操作将会变得基本一致,作为一个用户,你很难分出你是在操作互联网的数据还是本机。
# DSharp 发表于2006-08-06 09:45:00 IP: 221.0.182.*
再补充一点,5年之后,硬盘技术将会象原来的软盘一样逐步被淘汰,因为它太慢而且不安全,100倍硬盘速度的Flash存储技术取而代之,内存和外存将不会有太大的差别,HD-DVD成为标准配置。CRT技术成为历史。
# TripleX 发表于2006-08-06 12:46:00 IP: 61.51.71.*
to DSharp
flash是不行的 至少离 内存和外存将不会有太大的差别 差很远 现在flash有两种 nand和nor nor型的读和rom差不多 但是写是按照block写的 而且必须先擦除再写 每个block大小为64k-256k 很大的 擦除速度也很慢 写速度根本没法和硬盘比 更别说内存了 nand就更离谱了 整个就是一个块设备 无论那种flash 块的擦除次数都是有限的 所以flash上的文件系统的块分配策略和硬盘完全不同 现在的OS如果在flash上直接跑 很快就会把它搞坏
读写都按块的 8-16核心的cpu现在就有卖 broadcom cavium都有很多核的mips 但是为它们做优化不是这么简单的
# sevencat 发表于2006-08-07 10:22:00 IP: 218.242.214.*
TO:DSharp
我从来不预测,我只是根据现有的情况稍微考虑一下将来。
NT4还是2k(我记不得了)已经是真正的支持SMP的多任务操作系统了。
笔记本电脑取代台机?
我并不这样认为,笔记本的键盘和显示器你觉得很好用吗?
# Anonymous 发表于2006-08-07 16:11:00 IP: 207.46.89.*
这里面高谈阔论的不少,但是没有人谈论memory model , memory barrier, full fence, 在windows, linux, .net framework, jvm上的定义。
在单cpu上的多线程不一定能运行在多内核的cpu上。
# TripleX 发表于2006-08-08 01:20:00 IP: 222.128.6.*
小声问一下 不写硬件驱动的话 需要memory barrier吗? 我似乎只在写硬件驱动的时候用过
# Anonymous 发表于2006-08-08 09:45:00 IP: 207.46.89.*
虽然memory barrier 通常是由同步的一些机制封装了,但很多情况下,应用程序也需要了解这些机制,这通常发生在app想聪明的避免锁的开销,考虑一下double check在JVM, .NET framework 1.0上的问题, 而.NET framework 2.0上的memory model上所有的writer都是store.release,所以不会有类似的问题。
迄今为止所有预言CPU Performance足够的预言都被证明是错的。当cpu采取scale out而不是scale up的方式去继续moore's law, 普通程序性能不会直接随着内核增加而提高,可以预见更多的内核会出现,intel得文档已经在讨论超过100核,到那个时候,如果你的程序不能很好地把工作分到多个线程上,还会有人用吗?
# Anonymous 发表于2006-08-08 09:37:00 IP: 207.46.89.*
虽然memory barrier 通常是由同步的一些机制封装了,但很多情况下,应用程序也需要了解这些机制,这通常发生在app想聪明的避免锁的开销,考虑一下double check在JVM, .NET framework 1.0上的问题, 而.NET framework 2.0上的memory model上所有的writer都是store.release,所以不会有类似的问题。
# F# 发表于2006-08-08 13:36:00 IP: 218.22.16.*
你的程序如果只有一个主线程,那么再多颗核、再多颗CPU也救不了你;如果你运用了线程池之类的东东,在单核的机器上跑得一样呱呱叫。多核的界面肯定会在硬件层上隐藏起来,否则只会把东西越搞越复杂而不是变简单。
# phoenixsh 发表于2006-08-08 14:21:00 IP: 222.67.11.*
100核?恐怕首先是对电子工程师的重大挑战,希望不会出来耗电量1000瓦的怪物。从双核到100核,也许不仅仅是数量上的变化那么简单。
其次,这对存储器和操作系统是很大的挑战。
# redsea 发表于2006-08-08 15:00:00 IP: 124.248.72.*
>这里面高谈阔论的不少,但是没有人谈论memory model , memory barrier, full fence, 在windows, linux, .net framework, jvm上的定义。
memory barrier 是个什么东西? 看后面的说法是不是和spin_lock 相象? 用 busy check 取代 block wait 等待某些可以快速使用完毕的临界资源?
如果是这个东西, 似乎不是什么很大的话题,如果我要用的话,我会参照 boost 里面的实现来做,那里面有维护share_ptr 引用计数的代码,没有用mutex, 而是自己写汇编指令来保护资源,目前已经支持 powerpc, x86, ia64, spare, 我想要的 arm 和mips还没有支持。
# redsea 发表于2006-08-08 15:03:00 IP: 124.248.72.*
靠,我的debian xorg 升到7之后, opera 一直用不了,刚才写的东西konqueror 看不到验证码无法提交,copy & paste 到 firefox 里面就丢失了很多个字。
>这里面高谈阔论的不少,但是没有人谈论memory model , memory barrier, full fence, 在windows, linux, .net framework, jvm上的定义。
memory barrier 是个什么东西? 看后面的说法是不是和spin_lock 相象? 用 busy check 取代 block wait 等待某些可以快速使用完毕的临界资源?
如果是这个东西, 似乎不是什么很大的话题,如果我要用的话,我会参照 boost 里面的实现来做, 那里面有维护share_ptr 引用计数的代码,没有用mutex, 而是自己写汇编指令来保护资源,目前已经支持 powerpc, x86, ia64, sparc, 我想要的 arm 和mips还没有支持。
# 云风 发表于2006-08-08 21:17:00 IP: 218.72.95.*
memory barrier 的问题,我倒觉得即使是对应用程序也是很有用的,对提高多线程程序的性能很有意义。可惜我做的是网络游戏 client, 要照顾各种用户的机器,一直没有去用,了解也不算太多。我自己的理解是,解决的是多核间共享内存 cache 同步的问题。
"在单cpu上的多线程不一定能运行在多内核的cpu上。" 这句话我个人不太赞同,如果事实如此,只能是程序没实现好罢了。
的确,在单 cpu 上可以默认一些事实,而偷偷省略一些锁而不会出错。而这正是设计的 bug ,只不过让程序碰巧在单 cpu 上能跑罢了。
记得去年翻过一些 intel 的文档,感觉至少在目前的机器上,用 memory barrier 来解决的问题,换成 lock 指令,还只是效率问题。
double check 的确有问题,我个人觉得,觉得这个问题的根本途径是在设计上避免使用它。前段写过篇 blog , http://blog.codingnow.com/2006/05/manage_resource.html
也是由这个问题而引出的。
# TripleX 发表于2006-08-09 02:12:00 IP: 222.128.6.*
在单CPU的x86和arm(version < 6)下面 memory barrier其实就是告诉编译器 把变量直接写到内存里 因为编译器优化的原故 很多临时变量都是保存在寄存器里的 对gcc来说 加上一条特殊的空asm指令 编译器就会把寄存器保存回内存 这时mb的定义就是
__asm__ __volatile__ ("" : : : "memory");
在某些体系结构中就不一样了 比如powerpc armv6内存实际的写的顺序和store指令的顺序并不一致 如果只是对用户进程而言 没有什么问题 因为CPU读内存的时候其实是读cache 内存写的顺序并没有关系 哪怕完全没有写到内存里 cpu读出来的数据都是正常的 但是写硬件驱动的时候就不一样了 比如一个硬件有两个寄存器 一个是索引 一个是数据 正常的流程是先写索引 再写数据 但是写操作其实只是写到cache 由cache到总线是被重新排序的 所以有可能先写数据寄存器后写索引寄存器 这样就乱套了 因此还要加入一些指令来确保数据写到内存 比如powerpc下的sync指令 (即使用指令把对应的cache line失效 powerpc也不保证写入的顺序和指令执行的顺序一致....)
不涉及到硬件IO的话
__asm__ __volatile__ ("" : : : "memory");
对单cpu 就可以了 即使是那些weekly order的cpu 象powerpc 因为对cpu来说 读的永远是cache ram的写入顺序并不重要 SMP的情形我没看过资料 有空看看去 或者谁给讲讲 :-)
# Anonymous 发表于2006-08-09 09:36:00 IP: 207.46.89.*
由于硬件的差别,不同的cache hierarchy, 不同的core共享某些cache但是不共享另外一些cache,因为从data的角度,每个thread看到的内容可以说是随机的,所以软件是不能直接使用这种定义的,所以memory model用来将thread和memory之间的关系抽象出来。这个抽象的过程是把时间上的随机性model成空间上的随机性。在这样的model中,你不需要直接考虑cache,总线,寄存器的影响,这些影响反映在store 和load的次序可以被打乱。
你可以用memory barrier或者锁来控制那些store, load的次序可以被打乱,那些不可以。所有的锁底层都是使用memory barrier来控制次序(order)
不同层次的软件使用不同的抽象过程,这个抽象代表了比如.net framework, jvm有自己的memory model, 去网上看看spec, OS也一样, 现在的kernel mode的同步机制在必要的时候都使用了memory barrier (fence), 具体的实现不一定对应到cpu 上的memory barrier 指令(mb),比如linux和WINDOWS的memory barrier可以用xchg实现,所以我前面提到的memory barrier不是指某个cpu的指令,而是指在memory model中的概念。(这些上层的命令可以同时禁止相关编译器优化, 硬件上的memory barrier是处理program order 和execution order之间的关系)
Volatile:
在clr中,除了直接内存读写外, volatile read 还具有load.acquire语义,volatile write 具有store.release语义,关于acquire,release 可以看看cpu manual. 这个定义和以前c中的volatile 是不一样的,但是cl 14后,volatile 已经和clr 中的一致了。
“在单cpu上的多线程不一定能运行在多内核的cpu上“ 原因在于以前的x86的memory model是一个strong的memory model, all load has load.acquire semantic, all store has store.release semantic, 所以在weaker memory model上出错是不奇怪的。
double check在.net framework 2.0上should work, 因为clr 2.0里面, all store have store.release semantic.
weaker memory model对developer是个挑战,不过这是为了提高性能做出的妥协,正确的使用锁应该可以避免这些问题。但是作为developer, 应该了解现在的锁和以前的锁的实现机制的不同,这样在试图避免使用锁时候才不会犯错。
有兴趣地可以看看software transaction memory (lock free concurrence control)这些都还在研究中,也许过几年runtime都可以集成进这样的机制,那时我们的工作可以容易一些。
写的太乱了,凑合看吧。
# TripleX 发表于2006-08-09 11:22:00 IP: 61.51.72.*
Anonymous写得不错 不过我还是有点不明白 在多核的情况下 A cpu写了数据 B cpu看到的写顺序有问题这个容易理解 但是B cpu什么时候能看到这些改变呢? 立刻 还是不确定的时间之后? 我在user mode下从来没有见过要用cache invlid的地方 相必是立刻更新的吧 也许只是某些地方的写顺序改变了 而同时性上相差很少
ps 硬件上的memory barrier不仅是处理program order 和execution order之间的关系 而且还处理memory order和execution order之间的关系
# TripleX 发表于2006-08-09 11:25:00 IP: 61.51.72.*
Anonymous写得不错 不过我还是有点不明白 在多核的情况下 A cpu写了数据 B cpu看到的写顺序有问题这个容易理解 但是B cpu什么时候能看到这些改变呢? 立刻 还是不确定的时间之后? 我在user mode下从来没有见过要用cache invlid的地方 相必是立刻更新的吧 也许只是某些地方的写顺序改变了 而同时性上相差很少
ps 硬件上的memory barrier不仅是处理program order 和execution order之间的关系 而且还处理memory order和execution order之间的关系
# TripleX 发表于2006-08-09 11:29:00 IP: 61.51.72.*
Anonymous写得不错 不过我还是有点不明白 在多核的情况下 A cpu写了数据 B cpu看到的写顺序有问题这个容易理解 但是B cpu什么时候能看到这些改变呢? 立刻 还是不确定的时间之后? 我在user mode下从来没有见过要用cache invlid的地方 相必是立刻更新的吧 也许只是某些地方的写顺序改变了 而同时性上相差很少
ps 硬件上的memory barrier不仅是处理program order 和execution order之间的关系 而且还处理memory order和execution order之间的关系
# lucky_kmj 发表于2006-09-27 21:26:00 IP: 218.244.90.*
用两个线程做累加的结果:
测试机器是napa420 1.6G单核和napa core 2300 1.66G双核
PC:M420
input interval value:
100
Starting thread: main thread
main thread:count has reached 100
main thread:count has reached 200
main thread:count has reached 300
main thread:count has reached 400
main thread:count has reached 500
main thread:count has reached 600
main thread:count has reached 700
main thread:count has reached 800
main thread over!!! Time passed: 0'0''
Starting thread: child thread
child thread:count has reached 100
child thread:count has reached 200
child thread:count has reached 300
child thread:count has reached 400
child thread:count has reached 500
child thread:count has reached 600
child thread:count has reached 700
child thread:count has reached 800
child thread over!!! Time passed: 0'0''
不稳定,有100,15’’还有100000,15’’和0’’
input interval value:
1000000
Starting thread: main thread
main thread:count has reached 1000000
Starting thread: child thread
child thread:count has reached 1000000
child thread:count has reached 2000000
child thread:count has reached 3000000
child thread:count has reached 4000000
child thread:count has reached 5000000
child thread:count has reached 6000000
child thread:count has reached 7000000
child thread:count has reached 8000000
child thread over!!! Time passed: 0'78''
main thread:count has reached 2000000
ma
# zcpro 发表于2006-10-10 12:03:00 IP: 124.156.124.*
多线程是趋势,但是单线程也不会消亡。单线程程序开发难度低,稳定性高,而且即使cpu是多核,还可以通过多进程(同时开多个单线程程序)来同样达到充分利用硬件资源的效果。
看到上面lucky_kmj同志的回复,就再加一点,如果在双核上同时执行两个无关的任务,那么理论上的效率是单核的两倍,没错;但是一个具体的应用往往很难把它切成独立无关的几个部分,假设一个程序有1%的任务不能并行执行(即需要同步),那么多核心带来的效率提高最高100倍,50%不能并行执行时最高2倍,有10000个核心也没用。
# BUBsky 发表于2006-12-24 19:10:52 IP: 218.0.151.*
小声说句:
貌似现在PC主要的瓶颈在硬盘的传输速度了,毕竟现在内存的速度还是比硬盘快N多的
# Fieldring 发表于2007-02-05 10:31:21 IP: 222.209.57.*
我想做一个多核环境下,编译算法的研究,要考虑到多线程,资源共享,死锁,并行等等问题。myan有什么好的建议,或推荐点资料吗?谢谢
# citypunk 发表于2007-06-30 17:53:47 IP: 202.103.100.*
多CPU的Server开发多线程程序更有优势,可惜C++标准没有多MT的描述,有第三方的Boost,zhread,ACE等支持多线程模型,但是学习成本比较高,Java环境下使用多线程明显Easy些
分类: 多核技术

