分类 高性能计算 下的文章

CUDA与C++联合编程很常见,在Matlab工程中很少出现,当Matlab工程很庞大时,将Matlab库函数移动到C++工作量非常大,并且数值精度也无法保证。本文介绍在Matlab环境下CUDA编程。

首先确定有支持CUDA的Nvidia显卡,并且已经正确安装好驱动和SDK等,网上有许多CUDA安装与配置环境的教程。Matlab与CUDA混合编程,首先使用Matlab,C++混合编程,最后C++作为中间介质与CUDA进行调用。(本文测试环境:Win7x64,Matlab2012b,CUDAv6.5)

1、Matlab与C++混合编程

  • 在matlab的CommandWindow里输入mex –setup,选择C++编译器;
  • 测试example
    #include "mex.h"
    // nlhs:输出变量的个数
    // plhs:输出的mxArray矩阵的头指针
    // nrhs:输入变量个数
    // prhs:输入的mxArray矩阵的头指针
    void mexFunction(int nlhs,mxArray* plhs[],int nrhs,const mxArray* prhs[])
    { 
       mexPrintf("Hello, matlab with cuda!\n");
    }
  • 编译C++代码:mex helloMex.cpp,如果成功的话,将产生helloMex.mexw64(或helloMex.mexw32),在Matlab命令行输入helloMex则会输出结果。

mexFunction()是Matlab混合编程必须的函数,作为接口函数,进行参数的传递。

- 阅读剩余部分 -

1、fork/join并行执行模式
OpenMP是一个编译器指令和库函数的集合,主要是为共享存储计算机上的并行程序设计使用的。
标准并行模式(fork/join并行模式)执行代码的基本思想是,程序开始只有一个主线程,程序中的串行部分都由主线程执行,并行的部分通过派生其他线程来执行,如果串行部分没有执行结束,接下来的串行部分必须要等待子线程中并行部分执行完毕才能继续推进。
例如:

int main(int argc, char* argv[])
{
      clock_t t1 = clock();
      #pragma omp parallel for
      for ( int j = 0; j < 2; j++ ){
          test();
      }
      clock_t t2 = clock();
      printf("Total time = %d\n", t2‐t1);
   
      test();
      return 0;
}

在没有执行完for循环中的代码之前,后面的clock_t t2 = clock();不会执行,如果和调用线程创建函数相比,它相当于先创建线程,并等待线程执行完毕,所以这种模式中在主线程里面创建的线程并没有和主线程并行运行

- 阅读剩余部分 -

OpenMP(Open Multi-Processing)是一套支持跨平台共享内存方式的多线程并发的编程API,使用C,C++和Fortran语言,可以在大多数的处理器体系和操作系统中运行,包括Solaris, AIX, HP-UX, GNU/Linux, Mac OS X, 和Microsoft Windows。包括一套编译器指令、库和一些能够影响运行行为的环境变量。— —维基百科OpenMP

1、相比传统多线程编程,OpenMP(多核编程)具有以下优点:

  • CPU核数拓展性问题

多核编程需要考虑程序性能随CPU核心数的拓展性,当硬件升级到多核后,能够不修改程序让程序性能增长,这要求程序中的线程数要随CPU核数变化,不能创建定数线程,否则当CPU核数超过线程数,将无法发挥CPU性能,这正是OpenMP的优势。

  • 方便性问题

多核计算时,要求将计算分摊到各个CPU核上,所有的程序都需要并行执行,对计算的负载均衡有很高的要求。操作系统API创建线程时,需要线程入口函数,很难满足这个要求,除非将一个函数内的代码分拆成多个入口函数,这将大大增加程序员的工作量,使用OpenMP不需要入口函数,可以将同一函数内代码分解成多个线程执行,也可以将一个for循环分解成多个线程执行。

  • 可移植性问题

OpenMP是标准规范,所有支持它的编译器都是执行同一套标准,不存在可移植性问题。

- 阅读剩余部分 -