浅谈多核CPU、多线程与并行计算

xiaofei0859 2017-05-09 17:07:11  3646  收藏

展开

0.前言

笔者用过MPI和C#线程池,参加过比赛,有所感受,将近一年来,对多线程编程兴趣一直不减,一直有所关注,决定写篇文章,算是对知识的总结吧。有说的不对的地方,欢迎各位大哥们指正:)

1.CPU发展趋势

核心数目依旧会越来越多,依据摩尔定律,由于单个核心性能提升有着严重的瓶颈问题,普通的桌面PC有望在2017年末2018年初达到24核心(或者16核32线程),我们如何来面对这突如其来的核心数目的增加?编程也要与时俱进。笔者斗胆预测,CPU各个核心之间的片内总线将会采用4路组相连:),因为全相连太过复杂,单总线又不够给力。而且应该是非对称多核处理器,可能其中会混杂几个DSP处理器或流处理器。

2.多线程与并行计算的区别

(1)多线程的作用不只是用作并行计算,他还有很多很有益的作用。

还在单核时代,多线程就有很广泛的应用,这时候多线程大多用于降低阻塞(意思是类似于

while(1)

{

if(flag==1)

break;

sleep(1);

}

这样的代码)带来的CPU资源闲置,注意这里没有浪费CPU资源,去掉sleep(1)就是纯浪费了。

阻塞在什么时候发生呢?一般是等待IO操作(磁盘,数据库,网络等等)。此时如果单线程,CPU会干转不干实事(与本程序无关的事情都算不干实事,因为执行其他程序对我来说没意义),效率低下(针对这个程序而言),例如一个IO操作要耗时10毫秒,CPU就会被阻塞接近10毫秒,这是何等的浪费啊!要知道CPU是数着纳秒过日子的。

所以这种耗时的IO操作就用一个线程Thread去代为执行,创建这个线程的函数(代码)部分不会被IO操作阻塞,继续干这个程序中其他的事情,而不是干等待(或者去执行其他程序)。

同样在这个单核时代,多线程的这个消除阻塞的作用还可以叫做“并发”,这和并行是有着本质的不同的。并发是“伪并行”,看似并行,而实际上还是一个CPU在执行一切事物,只是切换的太快,我们没法察觉罢了。例如基于UI的程序(俗话说就是图形界面),如果你点一个按钮触发的事件需要执行10秒钟,那么这个程序就会假死,因为程序在忙着执行,没空搭理用户的其他操作;而如果你把这个按钮触发的函数赋给一个线程,然后启动线程去执行,那么程序就不会假死,继续相应用户的其他操作。但是,随之而来的就是线程的互斥和同步、死锁等问题,详细见有关文献。

现在是多核时代了,这种线程的互斥和同步问题是更加严峻的,单核时代大都算并发,多核时代真的就大为不同,为什么呢?具体细节请参考有关文献。我这里简单解释一下,以前volatile型变量的使用可以解决大部分问题,例如多个线程共同访问一个Flag标志位,如果是单核并发,基本不会出问题(P.S.在什么情况下会出问题呢?Flag有多个,或者是一个数组,这时候只能通过逻辑手段搞定这个问题了,多来几次空转无所谓,别出致命问题就行),因为CPU只有一个,同时访问这个标志位的只能有一个线程,而多核情况下就不太一样了,所以仅仅volatile不太能解决问题,这就要用到具体语言,具体环境中的“信号量”了,Mutex,Monitor,Lock等等,这些类都操作了硬件上的“关中断”,达到“原语”效果,对临界区的访问不被打断的效果,具体就不解释了,读者可以看看《现代操作系统》。

(2)并行计算还可以通过其他手段来获得,而多线程只是其中之一。

其他手段包括:多进程(这又包括共享存储区的和分布式多机,以及混合式的),指令级并行。

ILP(指令级并行),x86架构里叫SMT(同时多线程),在MIPS架构里与之对应的是super scalar(超标量)和乱序执行,二者有区别,但共同点都是可以达到指令级并行,这是用户没法控制的,不属于编程范围,只能做些有限的优化,而这有限的优化可能只属于编译器管辖的范畴,用户能做的甚少。

(3)典型的适于并行计算的语言

Erlang和MPI:这两个前者是语言,后者是C++和Fortran的扩展库,效果是一样的,利用多进程实现并行计算,Erlang是共享存储区的,MPI是混合型的。

C#.NET4.0:新版本4.0可以用少量代码实现并行For循环,之前版本需要用很繁琐的代码才能实现同样功能。这是利用了多线程实现并行计算。Java和C#3.5都有线程池(ThreadPool),也是不错的很好用的多线程管理类,可以方便高效的使用多线程。

CUDA,还是个初生牛犊,有很大的发展潜力,只不过就目前其应用领域很有限。其目前只能使用C语言,而且还不是C99,比较低级,不能使用函数指针。个人感觉这由于硬件上天生的局限性(平均每个核心可用内存小,与系统内存通讯时间长),只适用于做科学计算,静态图像处理,视频编码解码,其他领域,还不如高端CPU。等以后GPU有操作系统了,能充分调度GPU资源了,GPU就可以当大神了。游戏中的物理加速,实际上多核CPU也能很好的做到。

其他语言。。。恩。。留作将来讨论。

3.线程越多越好吗?什么时候才有必要用多线程?

线程必然不是越多越好,线程切换也是要开销的,当你增加一个线程的时候,增加的额外开销要小于该线程能够消除的阻塞时间,这才叫物有所值。

Linux自从2.6内核开始,就会把不同的线程交给不同的核心去处理。Windows也从NT.4.0开始支持这一特性。

什么时候该使用多线程呢?这要分四种情况讨论:

a.多核CPU——计算密集型任务。此时要尽量使用多线程,可以提高任务执行效率,例如加密解密,数据压缩解压缩(视频、音频、普通数据),否则只能使一个核心满载,而其他核心闲置。

b.单核CPU——计算密集型任务。此时的任务已经把CPU资源100%消耗了,就没必要也不可能使用多线程来提高计算效率了;相反,如果要做人机交互,最好还是要用多线程,避免用户没法对计算机进行操作。

c.单核CPU——IO密集型任务,使用多线程还是为了人机交互方便,

d.多核CPU——IO密集型任务,这就更不用说了,跟单核时候原因一样。

4.程序员需要掌握的技巧/技术

(1)减少串行化的代码用以提高效率。这是废话。

(2)单一的共享数据分布化:把一个数据复制很多份,让不同线程可以同时访问。

(3)负载均衡,分为静态的和动态的两种。具体的参见有关文献。

浅谈多核CPU、多线程与并行计算相关推荐

  1. linux的多任务 多进程,浅谈linux模拟多线程崩溃和多进程崩溃

    结论是: 多线程下如果其中一个线程崩溃了会导致其他线程(整个进程)都崩溃: 多进程下如果其中一个进程崩溃了对其余进程没有影响: 多线程 #include #include #include #incl ...

  2. 【kafka】浅谈Kafka的多线程消费的设计

    1.概述 转载:浅谈Kafka的多线程消费的设计 看原文去... 一.前言 跟RabbitMQ相比,Kafka的分区机制(Partition)使其支持对同一个"队列"分片并行读取, ...

  3. 深入浅谈,CPU设计原理

    首先,声明这是一篇转载文,这篇文章是,从卡饭论坛 看到的一篇文章<深入浅谈,CPU设计原理>,是一篇连载,文章,卡饭论坛,是我高中的时候,经常去的论坛,里面有很多好的文章,推荐给大家.也许 ...

  4. 浅谈易语言多线程 by逆风

    一.简介 1.线程句柄与线程: ①.关闭线程句柄对线程的运行不会有影响,关闭句柄并不代表结束线程: ②.线程句柄是用于对线程挂起.恢复.结束等操作,线程创建后,都会有一个线程句柄,如果不需要对线程句柄 ...

  5. 浅谈关于CPU的架构和工艺(1)

    http://www.jianshu.com/p/fa7e11321cd8 inside 高通骁龙 刚入手了SONY Xperia Z5 Premium,其CPU采用了争(fa)议(re)较大的骁龙( ...

  6. 浅谈Volatile与多线程

    http://renyan.spaces.eepw.com.cn/articles/article/item/86826 随着多核的日益普及,越来越多的程序将通过多线程并行化的方式来提升性能.然而,编 ...

  7. 多线程与单核cpu,多核cpu概念

    1.多线程在单核和多核CPU上的执行效率问题的讨论  a1: 多线程在单cpu中其实也是顺序执行的,不过系统可以帮你切换那个执行而已,其实并没有快(反而慢)  多个cpu的话就可以在两个cpu中同时执 ...

  8. 对多线程程序,单核cpu与多核cpu如何工作相关的探讨

    对多线程程序,单核cpu与多核cpu如何工作相关的探讨 我们程序员在编码的时候,涉及到技术方案时,往往会忽略掉代码对性能方面的影响,或者没有足够的敏感度来帮助自己判断自己的技术方案对系统性能造成的影响 ...

  9. 对于多线程程序,单核cpu与多核cpu是怎么工作的

    此文中的大部分资料来自于网络上,我只是觉得把有道理的整理一下,方便以后查阅. 1.多线程在单核和多核CPU上的执行效率问题的讨论 a1: 多线程在单cpu中其实也是顺序执行的,不过系统可以帮你切换那个 ...

最新文章

  1. Eclipse中jsp、js文件编辑时,卡死现象解决汇总
  2. 我理解的session和cookie
  3. REST技术第四步 多个參数注解问题
  4. java8 多个字段分组_MySQL基础之分组查询
  5. UNIX 网络编程知识,函数积累
  6. 新字符设备驱动实验(自动分配设备号、自动创建应用层设备节点、新字符设备注册到内核的结构体)
  7. 关联表多数据的批量insert (批量导入,测试19W条数据用时46秒)
  8. idea启动tomcat没有加载项目_震惊!我三步就搞定了 Tomcat 源码环境搭建!
  9. Java图片压缩 BufferedImage Linux 下代码阻塞不工作
  10. Fragment学习1--生命周期
  11. SQL Server数据库的兼容级别:错误;找不到xxxx对象
  12. PyCharm主题自定义
  13. android sqlite SQLiteDatabase
  14. python打开360浏览器_Selenium安装与360浏览器使用
  15. ANSYS Maxwell 2D永磁体建模
  16. 【计算机网络】—网络编程(socket)02
  17. STVP 烧录hex详细讲解
  18. TCC(TinyC)编译器汉化(中文编译器、汉语编程)之四:语法分析上
  19. 计算机系统漏洞及防范,计算机系统漏洞以及防范的措施.doc
  20. spfa - 黑暗城堡 - 一本通 3.1 例 1

热门文章

  1. 〖Java〗Eclispe安装和使用viplugin
  2. laravel安装笔记 (转)
  3. xCode自定义快捷键
  4. 中国象棋人机博弈程序(扁平化棋局) C语言实现
  5. java反射 invoke详解
  6. golang 去除 空白字符 含制表符
  7. linux make makefile 内置变量 默认变量
  8. linux c 命令行解析函数 getopt getopt_long
  9. linux tree命令 树结构显示目录文件
  10. Centos 6.5 初始安装无网卡驱动解决方法