1. 多核对于多线程来说会有多大的影响是否可以极大的提高多线程软件的执行效率
对于采用并行编程模型实现的多线程程序,多核处理器在低负载的情况下能很有效地提高执行效率,对于同一个应用,如果采用串行的编程模型,那么多核单核也就没什么区别了,如果该应用用并行算法来实现,并且改算法能将该应用的并行度提高到n,也就是说n个并行线程分别运行在n个核上时,不考虑n个线程之间的依赖性的话,本程序的速度就提高了n倍。
要利用多核的高吞吐能力,关键是有很好的并行算法最大限度地开发对象问题内在的并行性。
关键:算法本身的并行性。
2. 寻一篇多核程序设计的论文
We are dedicating all of our future proct development to multicore designs. We believe this is a key inflection point for the instry.
Intel President
Paul Otellini
Describing Intel’s future direction at the Developers Forum 2005
多核下的多线程程序设计与传统的单核下的多线程程序设计有着一定的差别,在单CPU下,是多个线程在同一个CPU上并发地执行,而在多核下,则是由多个线程在多个核上并行地执行。
但是,目前的程序设计中对于多核的利用并没有达到预期的效果。因此,为了能够在多核的环境下设计出更适合多核系统的程序,则是一个挑战。
要做到这一点,就必须将应用程序看做是众多相互依赖的任务的集合,将应用程序划分成多个独立的任务,并确定这些任务之间的相互依赖关系,这就称为分解(decomposition)。如下如示:
分解方式 设计 说明
任务分解 不同的程序行为采用不同的线程实现 常用于GUI应用程序
数据分解 多个线程对不同的数据块执行相同的操作 常用于音频、图像处理和科学计算应用程序
数据流分解 一个线程的输出作为另一个线程的输入 应注意尽量避免延迟
任务分解:对应用程序根据其执行的功能进行分解的过程称为任务分解(task decomposition)。根据这种方法,就能够对众多的独立任务进行分类。如果其中两个任务能够同时运行,那么开发人员就应该对其进行调度,形成二者之间的并行执行。
数据分解:数据分解也称为数据级并行(data-level parallelism)。是将应用程序根据各任务所处理的数据而非按任务来进行分解的方法,即以数据为中心。一般而言,能够按照数据分解方式进行分解的应用程序都包含多个线程,这些线程分别对不同的数据对象执行相同的操作。
数据流分解:在很多情况下,当对一个问题进行分解时,关键问题不在于采用一些什么任务来完成这个工作,而在于数据在这些任务之间是如何流动的。这个时候就要采用数据流分解方式,如典型的生产者/消费者问题。
对于任务分解,有两个需要注意的地方:
1. 划分的对象是计算,将计算划分为不同的任务
2. 划分后,研究不同任务所需的数据,如果这些数据不相交,则证明划分是成功的,如果数据有相当程序的相交,意味着要重新进行数据划分和功能划分。
如在一个气候模型中,需要考虑到地表模型、水文模型与海洋模型等多种情况,那么就应该将这几种模型划分成不同的任务,再分别进行并行地运算。
对于数据分解,划分的对象是数据,可以是算法的输入数据、中间处理数据和输出数据。在划分时应该考虑到数据上的相应操作。
最简单的情况下,比如对1000万个数进行相加,可以对其进行数据上的分解,用多个线程来分别计算不同批次的数据。然后再将计算的中间数据加到一起成为最终的结果。
--------------------------------------------------------------------------------
scutan 回复于:2008-07-09 21:50:58
1. 线程过多
线程并不是越多越好,对于某个程序,如果线程过多反而会严重地降低程序的性能。这种影响主要在于:
将给定的工作量划分给过多的线程会造成每个线程的工作量过少,因此可能导致线程启动和终止的开销比程序实际工作的时间还要多。
同时,太多并发线程的存在将导致共享有限硬件资源的开销增大。如保存和恢复寄存器状态的开销、保存和恢复线程cache状态的开销、废除虚存的开销、线程聚集在一起等待获取某个锁。
怎样解决这个问题:
限制可运行线程的个数
将计算线程与I/O线程分离开
使用已有的技术,如OpenMP,线程池等
2. 数据竞争、死锁
死锁,想必大家都很熟悉。这里谈谈一些简单的避免死锁的规则:
加锁的顺序是关键,使用嵌套的锁时必须保证以相同的顺序获取锁
防止发生饥饿:即这个代码的执行是否一定会结束。
不要重复请求同一个锁
越复杂的加锁方案越有可能造成死锁—设计应力求简单
3. 竞争激烈的锁
即使是正确使用锁来避免数据竞争,但如果各线程对锁的竞争很激烈,那么也会引发性能问题。即很多个线程来竞争同一个锁。在这个情况下,可以考虑将资源划分成若干个部分,然后用彼此独立的锁分别保护各个部分。即合理地安排加锁粒度的问题。在早期的linux内核中就使用了大内核锁,现在已经把锁给细划到不同的子系统中去了。
如果一个数据结构被频繁读取但不被频繁写入,就可以使用读写锁来解决竞争。
4. 线程安全函数
已有的一些函数并不是线程安全的,具体的线程安全函数可以参考APUE2上面的线程一章。
5. 存储效率问题
目前,处理器的速度已经比存储器快很多,一个处理器从内存中读或写一个值的时间内可以完成上百次的操作。因此,现在的程序往往受限于存储器的瓶颈。
首先,可以通过节省带宽,可以减少与存储器的数据交换数量,要节省带宽就要将数据压缩得更加紧凑。
其次是cache的利用。可以减少数据在不同CPU的cache间的移动。CPU亲合力(CPU Affinity)就是指在Linux系统中能够将一个或多个进程绑定到一个或多个处理器上运行。一个进程的CPU亲合力掩码决定了该进程将在哪个或哪几个CPU上运行,在一个多处理器系统中,设置CPU亲合力的掩码可能会获得更好的性能。
在下面的例子中讲解了如何利用将某个进程绑定以某个CPU上运行的实例。
http://linux.chinaunix.net/bbs/viewthread.php?tid=904906&extra=page%3D1%26amp%3Bfilter%3Ddigest
--------------------------------------------------------------------------------
scutan 回复于:2008-07-09 21:51:30
由于CPU运算速度的增长远远大于内存速度的增长,同时由于程序运行的局部性原理,所以现代计算机体系结构中引入了cache。
其实系统的存储器本身就是一个层次结构,从寄存器->高速缓存->主存->本地磁盘->颁布式文件系统。
在下面的贴子中的一个文档对cache方面讲解得非常不错,可以看看:
http://bbs.chinaunix.net/viewthread.php?tid=1022341&highlight=scutan
高速缓存的性能主要有以下几个方面:
1. 高速缓存的大小:
当CPU接收到指令后,它会最先向CPU中的一级缓存去寻找相关的数据,如果未命中,则继续向下一级的二级缓存中寻找。所以高速缓存越大,命中的机率也就越高。
2. 块大小的影响
大的块有利有弊,一方面,较大的块能利用程序中可能存在的空间局部性,帮助提高命中率。不过,对于给定的高速缓存的大小,块越大就意味着缓存行数越小,这会损害时间局部性比空间局部性更好的程序中的命中率。同时,因为块越大,传达时间也就越长。
3. 相联度的影响
较高的相联度的优点的降低了高速缓存由于冲突不命中出现抖动的可能性。不过,较高的相联度会造成较高的成本。
4. 前端总线的影响
现在的CPU技术发展很快,运算速度提高很大,而足够大的前端总线可以保障有足够的数据供给CPU,较低的前端总线将无法供给足够的数据给CPU,限制了CPU性能的发挥。
最后谈谈程序性能优化的相关内容。
对于程序性能的优化,首先应该考虑的架构以及算法这两方面的优化,最后再来考虑下面所讲述的这些优化。
消除连续的函数调用
消除不必要的存储器引用
通过展开循环降低循环开销
提高并行性
重新排列循环以提高空间局部性
让最常运行部分运行得更快
参考资料:
[1]. John L. Hennessy, David A. Patterson. 计算机体系结构:量化研究方法. 第4版
[2]. Shameem Akhter, Jason Roberts. 多核程序设计技术—通过软件多线程提升性能
[3]. Randal E. Bryant, David O’Hallaron. 深入理解计算机系统
[4]. Daniel P.Bovet, Marco Cesati. 深入理解Linux内核 第3版
http://www.chinaunix.net/jh/23/1193971.html
我抄的 自己拿回去看看
3. 多核编程与单核编程的区别
多核对于单核的好处是可以真正地同时处理多件事情,因此如果程序想要在多核CPU上获得更好的性能的话,使用多线程技术是必需的。但是采用多线程涉及到线程间数据同步的问题,程序员必须在线程间协调好对数据的访问和处理。
不过我觉得多核编程与单核编程的区别并不是指线程同步问题,因为单核编程同样可以使用多线程,同样需要面对线程同步的问题。同样的代码不经过特别优化,均可以在多核CPU和单核CPU上运行得很好,只不过运行效率不同罢了。
所以我觉得多核编程和单核编程的区别在于对多线程技术需求的迫切程度。如果程序针对多核环境来编程,那么必然要采用多线程技术,以获得更好的性能;如果程序只针对单核环境,那么对多线程并不是那么敏感,但如果它采用了多线程,一旦在多核环境运行,它也能获得性能的提升。
4. C语言中的MPI编程和多线程有什么区别,MPI编程中针对的是一台电脑多核还是多台电脑谢谢!
MPI(MPI是一个标准,有不同的具体实现,比如MPICH等)是多主机联网协作进行并行计算的工具,当然也可以用于单主机上多核/多CPU的并行计算,不过效率低。它能协调多台主机间的并行计算,因此并行规模上的可伸缩性很强,能在从个人电脑到世界TOP10的超级计算机上使用。缺点是使用进程间通信的方式协调并行计算,这导致并行效率较低、内存开销大、不直观、编程麻烦。OpenMP是针对单主机上多核/多CPU并行计算而设计的工具,换句话说,OpenMP更适合单台计算机共享内存结构上的并行计算。由于使用线程间共享内存的方式协调并行计算,它在多核/多CPU结构上的效率很高、内存开销小、编程语句简洁直观,因此编程容易、编译器实现也容易(现在最新版的C、C++、Fortran编译器基本上都内置OpenMP支持)。不过OpenMP最大的缺点是只能在单台主机上工作,不能用于多台主机间的并行计算!如果要多主机联网使用OpenMP(比如在超级计算机上),那必须有额外的工具帮助,比如MPI+OpenMP混合编程。或者是将多主机虚拟成一个共享内存环境(Intel有这样的平台),但这么做效率还不如混合编程,唯一的好处是编程人员可以不必额外学习MPI编程。
5. 我想精通C语言编程,求高手指导学习方案。(比如C如何实现多线程,和多核程序设计等等)
想精通C就必须要了解底层知识,尤其是编译原理,当你自己用C做出了一款C语言编译器,基本可以说是精通C了(编译器通常分两部分,其中一部分是与CPU相关的驱动程序,这个可以直接用现成的,但语法分析以及语义分析之类的的要自己写)。还有你问C如何实现多线程,我不太确定是什么意思?你是想用C程序通过调用现有的线程库来实现多线程编程还是想问如何用C现实出多线程的过程(也就是线程库的制作)?前者随便网上一搜就有一堆方法,后者基本只能在Linux上做,看看Linux内核中有关多线程实现的源代码就差不多了(建议先读一读Linux内核设计与实现第3版再看代码)
6. 2.3.4 多线程程序在多核和单核上运行的不同
锁:在单核上,多个线程执行锁或者临界区时,实际上只有一个线程在执行临界区代码,而核心也只支持一个线程执行,因此不存在冲突。如果某个线程持有锁,那么只是其他线程不会被调度到CPU上执行,影响的只是持有和释放锁的时间,处理器时刻在运行着。但是在多核上运行时,锁或临界区会导致其余处理器空闲而只允许一个处理器执行持有锁的那个线程,这是一个串行的过程,会影响性能。
负载均衡:在单核上不用考虑负载均衡,因为各个线程轮流执行,当一个线程执行完时,便会执行另一个线程,不存在线程等待问题。即使各个线程的任务非常不平衡,也不会影响总执行时间。而在多核上执行时,此时最终时间由运行时间最长的线程决定。
任务调度:单核上,任务调度完全是操作系统的工作,无须软件开发人员干预,通常有时间片轮转、优先级算法等。而在多核上运行时,软件开发人员要合理地在核心间分配任务,以尽量同时结束计算(此时任务调度的工作已经从操作系统转移到了软件开发人员)。
程序终止:在多线程环境中,何时终止程序就变得复杂,因为程序终止时需要确定各个线程都已经计算完成。幸运的是,多线程库通常都提供了对应的函数。在多机编程上,这个问题可能会变得非常复杂。
7. 多核多线程技术的内容简介
《多核多线程技术》就多核体系结构、芯片发展与系统软件,多性能并行程序,多线程程序的性能调优方法,多线程编程方法以及编程中的常见问题等作了综合讲述,处处体现了多线程编程理念与综合应用能力的培养。全书深入浅出,适合广大程序员和IT从事人员使用。
8. 关于多线程编程和CPU多核多线程的关系
原则上只要线程数不多于CPU核心数,会把各个线程都分配一个核心,不需分片,而当线程数多于CPU核心数时才会分片。事实上目前的计算机系统正常情况下线程数都是远远多于CPU核心数的,所以一般都要分片,以允许所有线程并发运行。
9. VC++ 多线程编程怎么充分利用多核CPU,并验
python由于GIL的关系,python的多线程并没有发挥多核的作用,这些线程都是在在单核上跑的 所以要想发挥多核的作用,就需要使用多进程,尽可能的在每一个CPU核心上分配到一个python进程。
所以要想跑满多核CPU就得多进程多线程互相结合
10. 多核编程和多线程编程有什么区别
有区别,多核编程是如何高效利用CPU去处理事务
多线程编程是 如何有效的处理事务。(个人理解,仅供参考~~)
一个是针对CPU,一个是针对事物本身