环境搭建与CUDA概述

2017-11-22  本文已影响0人  hyfine

[TOC]


环境搭建与CUDA概述

Deepin15.4 CUDA环境搭建

一、安装nvidia-bumblebee实现双显卡切换

sudo apt update
sudo apt install bumblebee bumblebee-nvidia nvidia-smi

一路yes安装下去,中间可能出现坑,安装过程中,明显听到显卡风扇疯狂转动,感觉电脑电脑爆炸了,无视之,安装完成后,重启,任然爆炸感,检查显卡情况。

lspci |grep VGA # 查看显卡
lspci |grep -i nvidia # 查看nvidia设备

发现nvidia独显是关闭状态的,但是风扇爆炸……关机(不是重启),再启动,正常了,不知道什么情况。

$ nvidia-smi
$ optirun nvidia-smi
# 以上两个命令查看驱动是否安装成功
# 第一个命令会显示一个启动失败的输出
#第二个命令实际是optimize run优化运行nvidia-smi,此时会输出nvidia显卡工作状态

二、安装CUDA开发工具,基于eclipse的nsight

由于cuda版本问题,需要将gcc降到4.8版本

# 安装4.8版本gcc和g++
sudo apt install g++-4.8 gcc-4.8
# 更改软连接
cd /usr/bin
sudo rm gcc g++
sudo ln -s g++-4.8 g++
sudo ln -s gcc-4.8 gcc

下载开发工具nsight

# 分别是开发环境、工具包、IDE、性能分析工具
sudo apt install nvidia-cuda-dev nvidia-cuda-toolkit nvidia-nsight nvidia-visual-profiler
$ optirun nsight
# 启动nsight集成开发环境,一定要optirun启动,否则编译通过无法启动独显运行

了解CUDA API

它们的区别与优缺点:

程序中任意部分可以自由选择使用任意一种类型的API,即可交叉使用。

/**
 * Thrust API的并行实现
 */
#include <iostream>
using namespace std;

#include <thrust/reduce.h>
#include <thrust/sequence.h>
#include <thrust/host_vector.h>
#include <thrust/device_vector.h>

int main_thrust(int argc, char const *argv[])
{
    const int N = 50000;

    // 创建数组,GPU设备中
    thrust::device_vector<int> a(N);
    // 填充数组,First元素值为0
    thrust::sequence(a.begin(),a.end(),0);
    // 并行计算数组元素和
    int sumA = thrust::reduce(a.begin(),a.end(),0);
    // 串行计算0到N-1的和
    int sumB = 0;
    for(int i=0;i<N;i++){
        sumB += i;
    }
    // 结果检测
    if(sumA == sumB)
        cout<<"Test Succeeded!"<<endl;
    else{
        cerr<<"Test Failed!"<<endl;
        return 1;
    }
    
    return 0;
}

编译运行

$ nvcc seqCuda.cu -o seqCuda
$ optirun ./seqCuda
/**
 * runtime API并行实现
 */

#include <iostream>
using namespace std;

#include <thrust/reduce.h>
#include <thrust/sequence.h>
#include <thrust/host_vector.h>
#include <thrust/device_vector.h>

/**
 * GPU代码,runtime API
 */
__global__ void fillKernel(int *a,int n){
    /**
     * 计算线程id
     * blockIdx.x=线程块序号
     * blockDim.x=每个线程块内的或维度线程数量???
     * threadIdx.x=用于定位该线程在线程块内的编号
     */
    int tid = blockIdx.x*blockDim.x+threadIdx.x;
    // 可能分配的线程数量多于N,这里只操作N范围内的线程
    if(tid<n)
        a[tid] = tid;
}

/**
 * CPU代码,计算所需的资源,以执行配置形式传入GPUkernel函数中
 */
void fill(int *d_a,int n){
    // 定义每个线程块包含的线程数
    int nThreadsPerBlock = 512;
    // 确定需要的线程块的数量
    int nBlocks = n/nThreadsPerBlock + ((n%nThreadsPerBlock)?1:0);
    // 调用GPU Kernel程序代码,传入执行配置(线程块,线程数/每个线程块)
    fillKernel<<<nBlocks,nThreadsPerBlock>>>(d_a,n);
}

int main_runtime() {
    const int N = 50000;
    // 创建数组
    thrust::device_vector<int> a(N);
    // 填充数组,用runtime api
    fill(thrust::raw_pointer_cast(&a[0]),N);
    // 计算数组元素和,thrust api
    int sumA = thrust::reduce(a.begin(),a.end(),0);
    // 串行计算和
    int sumB = 0;
    for(int i=0;i<N;i++){
        sumB+=i;
    }
    // 检验
    if(sumA==sumB)
        cout<<"Test Succeed!"<<endl;
    else{
        cerr<<"Test Failed!"<<endl;
        return 1;
    }
    return 0;
}

编译运行

$ nvcc seqRuntime.cu -o seqRuntime
$ optirun ./seqRuntime

基本概念

GPGPU编程三条法则

需要了解GPU内存的分布、使用机制,了解GPU线程的机制,以及CPU和GPU之间数据同步的过程。

CUDA和Amdahl定律

Amdahl是一种用以估算串行程序并行化之后的理想加速比,前提条件是并行化后问题尺度保持不变。

$$S(n)=\frac{1}{(1-p)+p/n}$$

其中,p为程序中可并行化的部分,分配给n个处理器上执行。

混合执行

同时使用CPU和GPU资源。多核处理器也是一种支持数据并行和任务并行的设备。OpenMP(open multi-processing)提供用于宿主处理器进行多线程程序开发的编程方式。nvcc编译器也支持OpenMP。

/**
 * CPU/GPU异步执行源代码
 * 其中CPU代码通过openMP多核并行执行
 */
#include <iostream>
using namespace std;

#include <thrust/reduce.h>
#include <thrust/sequence.h>
#include <thrust/host_vector.h>
#include <thrust/device_vector.h>

int main(){
    const int N = 50000;
    // 创建数组
    thrust::device_vector<int> a(N);
    // 填充数组,thrust GPU并行
    thrust::sequence(a.begin(),a.end(),0);
    // OpenMP CPU并行计算和
    int sumB = 0;
#pragma omp parallel for reduction(+:sumB)
    for(int i=0;i<N;i++)
        sumB+=i;

    // GPU并行计算数组和
    int sumA = thrust::reduce(a.begin(),a.end(),0);
    // 结果检查
    if(sumA==sumB)
        cout<<"Test Success!"<<endl;
    else{
        cout<<"Test Failed!"<<endl;
        return 1;
    }
    return 0;
}

编译运行

$ nvcc -O3 -Xcompiler -fopenmp seqAsync.cu -o seqAsync
$ optirun ./seqAsync
上一篇 下一篇

猜你喜欢

热点阅读