c++ 并行编程

本博客将看C++并行编程的例子

1. 线程进程原理

线程是轻量级的进程,一个进程可以拥有多个线程。

编译多线程程序加入 <pthread.h> 

g++ -lphread

2. openmp库加速

2.1 openmp库加速配置及hello,world

事实上有个openmp库,可以实现单台cpu的加速

Windows下使用vs
Configuration Properties->C/C++->Language->OpenMP Support,在下拉菜单里选择Yes。然后才能使用OpenMP
并行代码为例,只需要把相应的行注释掉,就是串行代码了
默认情况下,并行区内线程数=系统中核的个数

在Linux下使用g++即可

#include <stdio.h>
#include "omp.h"
int main()
{
  #pragma omp parallel
  printf( "Hello world!\n" );
  return 0;
}

g++ test.cpp
./a.out
输出一个
g++ -fopenmp  test.cpp
./a.out
输出12个,默认为cpu的逻辑核数(=cpu块数*cpu物理核数*(开启超线程*2))
export OMP_NUM_THREADS=6
./a.out
输出6个

一旦采用了OpenMP,线程数量就将由编译器来决定(而不是您),因此无论线程数量如何,重要的是使程序能够正常运行

2. 实战测试

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>

//一个简单的耗时任务
double Sum0(double* data,long data_count);

int main()
{
    long data_count=200000;
    double* data=new double[data_count];
    long i;

    //初始化测试数据 
    for (i=0;i<data_count;++i)
        data[i]=(double)(rand()*(1.0/RAND_MAX));

    const long test_count=200*2;//为了能够测量出代码执行的时间,让函数执行多次
    double sumresult=0;
    double runtime=(double)clock();
    for( i=0; i<test_count; ++i ) 
    {
        sumresult+=Sum0(data,data_count);
    }
    runtime=((double)clock()-runtime)/CLOCKS_PER_SEC;
    printf ("< Sum0 >  ");
    printf ("  最后结果     = %10.4f  ",sumresult);
    printf ("  执行时间(秒) = %f  ",runtime);

    delete [] data;
    return 0;
}


double Sum0(double* data,long data_count)
{
    double result=0;
    #pragma omp parallel for schedule(static) reduction(+: result)
    for (long i=0;i<data_count;++i)
    {
        data[i]=(double)sin(cos(data[i]));
        result+=data[i];
    }
    return  result;
}
在windows上

是否 OMP_NUM_TREADS 时间

无                     3.437s

有        2           1.586

有        4            1.349

有        8             1.46

在linux上

无           2.9036

有   12   13.9541

有    6      6.792




可以看到windows上做了将近三倍的加速,但是在linux上速度降低。可能是编程的方式不对。

下面将对其进行分析,希望能实现12倍加速



首先看如何看时间

#include <time.h>
#include <iostream>
using namespace std;


int main()
{
    clock_t startTime,endTime;
    startTime = clock();
    for (int i = 0; i < 10000000; i++)
    {
        i++;
    }
    endTime = clock();
    cout << "Totle Time : " <<(double)(endTime - startTime) / (CLOCKS_PER_SEC*1000) << "ms" << endl;
    return 0;
}

在linux上运行能看到结果 

[1] linux下查看核数

[2] windows下查看核数

[3] windows下openmp的配置 

[4] linux下openmp编程基础 

[5] c++并行与分布式编程[书籍]

posted @ 2017-05-02 17:31  开往春天的拖拉机  阅读(169)  评论(0编辑  收藏  举报