1、CPU核心/线程
假设一个4核心8线程CPU,每个核心支持2个线程并行运行(超线程技术 Hyper-threading)。
因为现在每个核心基本有一个Memory Management Unit (MMU) ,因此能够独立管理一个进程。使得进程间可以并行运行。
而利用超线程技术后的单个核心支持同时运行多个线程,因此也可以理解为单个核心上线程间也能并行运行。但这样的并行并不是完全并行,因为CPU执行一条指令时会有资源闲置,而超线程技术正是利用这种闲置,比如不同线程上的下一条指令不一样,一个是整数运算指令,另一个是浮点运算指令,这种情况下超线程技术便能使得双线程同时运行。但如果没法利用这种情况时,一个核心也仍然只能同时运行一个线程的指令。因此,前面提到的每个核心支持2个线程并行并不是完全并行,而是间歇式的并行。
因此简单理解为:多核实现真正的物理上的完全并行,而单核上的多线程是利用超线程技术实现物理上的部分并行。
举例
对于一个核心来说,如果不支持超线程技术,总是同一时间只能运行一个线程,利用时间片分割,进行线程间的切换。这种情况下,把一个程序分成多个线程不一定比单线程快,因为线程间的切换以及可能涉及的互斥锁等问题,都可能导致时间消耗更大,程序运行反而更慢。
但也有特殊情况,比如用python写爬虫,假设一个python程序运行在一个CPU核心上,并且使用多线程,一个线程请求一个url。此时请求不同的url时,因为每次请求后都会有等待,才能接收到服务器的response,因此这个时候多线程就能发挥作用了:CPU切换到另一个线程,进行下一个url的请求,而不是在第一个url请求后等待服务器的response。这种情况下,多线程则可能比单线程更快,因为中途本来就有等待时间,我们则可以在等待时执行另一个线程的任务。
对于一个核心来说,如果支持超线程技术,还是以python爬虫为例。这种情况下,不仅多线程能通过请求不同url来跳过等待时间,减少总的运行时间,并且超线程技术使得同时可能有多个线程的不同类型指令(如整数型和浮点型)同时运行在一个核心上。因此时间消耗会进一步缩短。
而对于多个核心,这种情况才属于真正的并行计算,还是以爬虫为例,假如请求1000个url,因为这些url之间是独立的,我们可以把前500个作为一个进程放在第一个CPU核心上,后500个作为另一个进程放在第二个CPU核心上。不同核心同时运行不同的进程,核心与核心之间互不干扰,这样则实现真正的并行,运行时间则会小于原来的1/2。
pytorch并行
Q&A
1、model.to(gpu) 和model.cuda(gpu) 起同样的作用,没有区别,都是把模型的参数传到指定GPU上 2、torch.distributed.barrier 是一个通用的barrier,使得所有进程在此处同步;但torch.distributed.init_process_group 后不需要单独使用该通用barrier来进行同步,因为此函数内置一个_store_based_barrier ,专门用于init_process_group 或者new_group 之后进行同步
|