Popular blog tags

并行优化是代码优化的基本方法,从大到小一共可以分成三级:异步框架;任务并行;数据并行。在实际工作中,一般是先设计异步框架,包括异步处理任务以及异步任务的异构化等;第二步一般是做数据并行优化(SIMD),利用CPU的向量指令来对多条数据并行处理;这两步是代码优化的重心,一般做完这两步,系统性能会有明显的提升。今天要讨论的是第三步,for循环的并行优化。与前两者不同的是,for循环往往是处理同一类任务,且通常会涉及到对同一个变量的读写,所以异步是不能用。

并行与并发

单核CPU处理系统只有并发,没有并行,它可以支持多个任务的运行,但是因为只有一个处理器,所以无法并行;

多核CPU处理器可以支持并行和并发,多个核可同时并行处理任务,而单核上也可以并发处理多个线程。

C++多线程与CPU多核多线程的关系

程序的多线程和CPU的多线程并不直接关联,底层的任务调度、线程调度都是操作系统来实现的。你只能告诉操作系统,这些工作是并行的,还是串行的,至于cpu怎么执行的,由于操作系统的线程调度,最终会把线程分配到每个核心上运行。

 

开一个死循环线程,线程里不要Sleep,目的就是让CPU满负荷跑,用SetThreadAffinityMask分别在不同的CPU上跑,从任务管理器中看CPU的负荷,你就知道线程跑在哪个CPU上。

我的电脑上时双CPU。
我在InitInstance中用:
bresult = SetProcessAffinityMask( GetCurrentProcess() , 3 ) ;
DWORD dwCPUid = SetThreadAffinityMask( GetCurrentThread() , 1 ) ; 
在另一个线程中使用
DWORD dwCPUid = SetThreadAffinityMask( GetCurrentThread() , 2 ) ;

但 两个线程还是一直CPU0上运行。

 

并行编程实现可选方案

Visual Studio c++使用并行模式库PPL、C++ AMP、OpenMP 以及与 Windows 多线程相关的其他功能

MPI:MPI实现并行是进程级;采用的是分布式内存系统,显式(数据分配方式)实现并行执行,通过通信在进程之间进行消息传递,可扩展性好。MPI虽适合于各种机器,但它的编程模型复杂

Qpar:自动并行化,加速代码执行的编译器优化。个人感觉最无脑的并行技术,对代码更改最小

AMP:允许使用现代图形处理器进行通用编程的类,就是GPU并行技术。MS最新的并行技术,代码更改最大
OpenMP:OpenMP是线程级(并行粒度);采用的是共享内存系统,隐式(数据分配方式)实现并行执行;可扩展性差;正因为采用共享内存分布系统,意味着它只适应于SMP(Symmetric Multi-Processing 对称多处理结构),DSM(Distributed Shared Memory 共享内存分布系统)机器,不适合于集群。OpenMP API的Microsoft实现。经典的外部并行技术库,很多科学计算都用这个,跨语言和平台。

C++ AMP实战:绘制曼德勃罗特集图像 https://www.cnblogs.com/Ninputer/archive/2012/01/03/2310945.html

OpenMP:OpenMP是线程级(并行粒度);采用的是共享内存系统,隐式(数据分配方式)实现并行执行;可扩展性差;正因为采用共享内存分布系统,意味着它只适应于SMP(Symmetric Multi-Processing 对称多处理结构),DSM(Distributed Shared Memory 共享内存分布系统)机器,不适合于集群。OpenMP API的Microsoft实现。经典的外部并行技术库,很多科学计算都用这个,跨语言和平台。

32 OpenMP Traps For C++ Developers  https://www.viva64.com/en/a/0054/

OpenMP in Visual C++ https://docs.microsoft.com/en-us/cpp/parallel/openmp/openmp-in-visual-cpp?view=vs-2019

 

c++并行计算库TBB:是intel开发的TBB,

c++并行计算库PPL:是微软开发的PPL。并发运行时(cocurrency runtime),数据并行或任务并行的类。功能很全面,相对比较简单  https://docs.microsoft.com/en-us/cpp/parallel/concrt/concurrency-runtime?redirectedfrom=MSDN&view=vs-2019

Windows *线程,

英特尔®线程构建模块进行并行编程

 

 

并行库-OpenMP

openMP支持的编程语言包括C语言、C++和Fortran,支持OpenMP的编译器包括Sun Studio,Intel Compiler,Microsoft Visual Studio,GCC.

step 1:Vs 2019 OpenMP环境配置

以Vs 2019作为IDE,C++作为开发语言,在正式进行OpenMP编码之前,需要对编译器稍微配置一下.

设置并行编译选项

建立工程后,点击 菜单栏->Project->Properties,弹出菜单里,点击 Configuration Properties->C/C++->Language->OpenMP Support,在下拉菜单里选择Yes。

//项目-属性- C/C++ - 语言 - OpenMP支持(是)

step 2:

//项目-属性- C/C++ - 语言 - OpenMP支持(是)
#include <omp.h>
...
#pragma omp parallel for
    for(int i = 0; i < 10; i++)
    {
        //dosome;
    }

#pragma omp atomic

对变量进行原子操作

size_t count = 0;
   int size = static_cast<int>(a.size());
   #pragma omp parallel for
      for (int i = 0; i < size; ++i)
      {
         if (is_prime(a[i])) {
            #pragma omp atomic
               ++count;
         }
      }

 

Parallel Loop SIMD Construct

From OpenMP 4.5 Specification:

The parallel loop SIMD construct is a shortcut for specifying a parallel construct containing one loop SIMD construct and no other statement.

The syntax of the parallel loop SIMD construct is as follows:

#pragma omp parallel for simd

You can also write:

#pragma omp parallel
{
   #pragma omp for simd
   for ...
}

 

PPL

C++ 中的并行编程

https://docs.microsoft.com/zh-cn/cpp/parallel/parallel-programming-in-visual-cpp?view=vs-2019

32 OpenMP Traps For C++ Developers

https://www.viva64.com/en/a/0054/

OpenMP in Visual C++

https://docs.microsoft.com/en-us/cpp/parallel/openmp/openmp-in-visual-cpp?view=vs-2019

openMP的一点使用经验

https://www.cnblogs.com/yangyangcv/archive/2012/03/23/2413335.html

并行计算,基于vs c++ OpenMP的并行编程

https://www.cnblogs.com/hantan2008/p/5961312.html

五种主要多核并行编程库分析与比较

https://blog.csdn.net/weixin_34344677/article/details/94054926