GPU简介

一般人眼中的GPU

  • 图形处理器(英语:graphics processing unit,缩写:GPU),又称显示核心、视觉处理器、显示芯片,是一种专门在个人电脑、工作站、游戏机和一些移动设备(如平板电脑、智能手机等)上做图像和图形相关运算工作的微处理器。

-我曾经也一度的认为GPU只是针对图像处理的,直到现在,某次课提到了一下,我尝试学习了它,才发现它的处理思维逻辑有点像FPGA(Field Programmable Gate Array),只不过GPU可以进行浮点运算。GPU的主频也还是蛮高的。其他具体的介绍度娘都可以为你解答,耐心看就行。
-废话不多说,我也不是很了解GPU,这篇文章也只是一个初步探索,谈不上精通,有一点当年用FPGA并行的舒爽吧。这里主要是从两个例子来介绍,第一个则是,cuda程序并行计算,另一个个是cuda加速的cufft与fftw相比。毕竟我的目的是尽可能的使得SDR可以实时。

硬件参数

做实验,不说硬件配置都是流氓呀
CPU: AMD Ryzen 7 3700X 8-Core Processor @ 5.35781GHz
内存:16GB
操作系统:deepin20.02 社区版
显卡:Getforce RTX2060自打买了这电脑以来,还没用过显卡,可不能浪费啦

软件参数

这里主要是说一下我安装的显卡驱动什么的, 默认已经装好显卡驱动和cuda啦,我不做神经网络,所以不装cudann。
终端输入

nvidia-smi

结果如下:
显卡驱动教程,我看人家的:
deepin20 显卡驱动安装
这个稍微和别人有点不一样的,自己装的时候意会一下就好啦
deepin 安装ubuntu的cuda
cuda安装,首先取官网下一个cuda,我直接下debian的deb没装好,装的ubuntu 的.run
什么版本看自己显卡吧

注意大写

$ nvcc -V
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2021 NVIDIA Corporation
Built on Mon_May__3_19:15:13_PDT_2021
Cuda compilation tools, release 11.3, V11.3.109
Build cuda_11.3.r11.3/compiler.29920130_0

到这里环境就算是搭建好啦

这是正经事

这里的代码都是c++调用GPU加速,这是正常人干的事,一般不会反人类吧
GPU不能cout注意啦

并行计算测试

要注意的几个点呢,
1 库链接,可以绝对路径,这个自己品味
2 编译的时候加上库的名字也是可以的
3 CmakeLists.txt 这个好,,就讲这个吧
注意,CmakeLists.txt ,多加了关键词cuda,不然编译会出问题
cuda_add_executable(cuda_xxx xxx.cpp)

好啦到这就可以贴代码啦
官方例程也贴下吧:
main.cu

#include "cuda_runtime.h"
#include "device_launch_parameters.h"  #include <stdio.h>  cudaError_t addWithCuda(int *c, const int *a, const int *b, size_t size);  __global__ void addKernel(int *c, const int *a, const int *b)
{  int i = threadIdx.x;  c[i] = a[i] + b[i];
}  int main()
{  const int arraySize = 5;  const int a[arraySize] = { 1, 2, 3, 4, 5 };  const int b[arraySize] = { 10, 20, 30, 40, 50 };  int c[arraySize] = { 0 };  // Add vectors in parallel.  cudaError_t cudaStatus = addWithCuda(c, a, b, arraySize);  if (cudaStatus != cudaSuccess) {  fprintf(stderr, "addWithCuda failed!");  return 1;  }  printf("{1,2,3,4,5} + {10,20,30,40,50} = {%d,%d,%d,%d,%d}\n",  c[0], c[1], c[2], c[3], c[4]);  // cudaThreadExit must be called before exiting in order for profiling and  // tracing tools such as Nsight and Visual Profiler to show complete traces.  cudaStatus = cudaThreadExit();  if (cudaStatus != cudaSuccess) {  fprintf(stderr, "cudaThreadExit failed!");  return 1;  }  return 0;
}  // Helper function for using CUDA to add vectors in parallel.
cudaError_t addWithCuda(int *c, const int *a, const int *b, size_t size)
{  int *dev_a = 0;  int *dev_b = 0;  int *dev_c = 0;  cudaError_t cudaStatus;  // Choose which GPU to run on, change this on a multi-GPU system.  cudaStatus = cudaSetDevice(0);  if (cudaStatus != cudaSuccess) {  fprintf(stderr, "cudaSetDevice failed!  Do you have a CUDA-capable GPU installed?");  goto Error;  }  // Allocate GPU buffers for three vectors (two input, one output)    .  cudaStatus = cudaMalloc((void**)&dev_c, size * sizeof(int));  if (cudaStatus != cudaSuccess) {  fprintf(stderr, "cudaMalloc failed!");  goto Error;  }  cudaStatus = cudaMalloc((void**)&dev_a, size * sizeof(int));  if (cudaStatus != cudaSuccess) {  fprintf(stderr, "cudaMalloc failed!");  goto Error;  }  cudaStatus = cudaMalloc((void**)&dev_b, size * sizeof(int));  if (cudaStatus != cudaSuccess) {  fprintf(stderr, "cudaMalloc failed!");  goto Error;  }  // Copy input vectors from host memory to GPU buffers.  cudaStatus = cudaMemcpy(dev_a, a, size * sizeof(int), cudaMemcpyHostToDevice);  if (cudaStatus != cudaSuccess) {  fprintf(stderr, "cudaMemcpy failed!");  goto Error;  }  cudaStatus = cudaMemcpy(dev_b, b, size * sizeof(int), cudaMemcpyHostToDevice);  if (cudaStatus != cudaSuccess) {  fprintf(stderr, "cudaMemcpy failed!");  goto Error;  }  // Launch a kernel on the GPU with one thread for each element.  addKernel<<<1, size>>>(dev_c, dev_a, dev_b);  // cudaThreadSynchronize waits for the kernel to finish, and returns  // any errors encountered during the launch.  cudaStatus = cudaThreadSynchronize();  if (cudaStatus != cudaSuccess) {  fprintf(stderr, "cudaThreadSynchronize returned error code %d after launching addKernel!\n", cudaStatus);  goto Error;  }  // Copy output vector from GPU buffer to host memory.  cudaStatus = cudaMemcpy(c, dev_c, size * sizeof(int), cudaMemcpyDeviceToHost);  if (cudaStatus != cudaSuccess) {  fprintf(stderr, "cudaMemcpy failed!");  goto Error;  }  Error:  cudaFree(dev_c);  cudaFree(dev_a);  cudaFree(dev_b);  return cudaStatus;
}

用nvcc -c编译:

$nvcc -c main.cu
./main
{1,2,3,4,5} + {10,20,30,40,50} = {11,22,33,44,55}

这里是C++调用cuda的结果,代码干啥就随意啦
main-> add.cpp
add.h
kernel.cu
kernel.cuh (这里没用用)
kernel.h(也可以用.h文件)
add.cpp

#include "add.h"
#define M2 1000000
#define Dlen 100*M2void add(long int *a,long int *b,long int *c)
{for (long int f = 0; f<Dlen; f++){*c = (*a)*(*b);}}
int main(void)
{CTest cTest;long int a,b,c;a = 102400;b = 306900;clock_t time_used;clock_t start = clock();add(&a,&b,&c);cout << "CPU time use is " <<  (clock() - start)*1.0/CLOCKS_PER_SEC << endl;cTest.Evolution();}

add.h

#pragma once
// #include "/usr/local/cuda/include/cuda_runtime.h"
// #include "/usr/local/cuda/include/device_launch_parameters.h"
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
// #include "kernel.cuh"
#include "kernel.h"
#include <iostream>
using namespace std;
#define M 1000000
#define DX 100*Mclass CTest
{public:long int *a;long int *b;long int *c;void SetParameter();void AddNum();void Show();void Evolution();
};void CTest::SetParameter()
{cudaMallocManaged(&a, sizeof(long int) * DX);cudaMallocManaged(&b, sizeof(long int) * DX);cudaMallocManaged(&c, sizeof(long int) * DX);for (long int f = 0; f<DX; f++){a[f] = 102400;b[f] = 306900;}}void CTest::AddNum()
{AddKernel(a, b, c, DX);
}void CTest::Show()
{cout << " a     b    c"  << endl;for (long int f = 0; f<DX; f++){cout << a[f] << " + " << b[f] << "  = " << c[f] << endl;}
}void CTest::Evolution()
{SetParameter();clock_t time_used;clock_t start = clock();AddNum();cout << "GPU time use is " <<  (clock() - start)*1.0/CLOCKS_PER_SEC << endl;cout << "sum finish !!!" << endl;// Show();
}

kernel.cu

#include "kernel.h"
// #include "/usr/local/cuda/include/cuda_runtime.h"
// #include "/usr/local/cuda/include/device_launch_parameters.h"
#include "cuda_runtime.h"
#include "device_launch_parameters.h"__global__ void Add(long int *a,long int *b, long int *c,long int DX)
{int f = blockIdx.x*blockDim.x + threadIdx.x;if (f >= DX) return;c[f] = a[f]*b[f];}void AddKernel(long int *a, long int *b, long int *c, long int DX)
{dim3 dimBlock = (1024);dim3 dimGrid = ((DX + 128 - 1) / 128);Add << <dimGrid, dimBlock >> > (a, b, c, DX);cudaDeviceSynchronize();
}

kernel.cuh

void AddKernel(long int *a, long int *b, long int *c,long  int DX);

CMakeLists.txt

cmake_minimum_required (VERSION 2.8)
project  (Cpp_rungpu)
#significant note: gcc version 5.4.0
set(CMAKE_CXX_FLAGS "-std=c++11 -DNDEBUG -O2 ") ##-g
find_package(CUDA QUIET REQUIRED)
include_directories("${CUDA_INCLUDE_DIRS}")include_directories(/usr/local/include)
include_directories(/usr/local/cuda/include)
cuda_add_executable(Cpp_rungpu add.cpp kernel.cu )  ##关键语句
target_link_libraries(Cpp_rungpu)

readme这是一种编译方式

 nvcc -c kernel.cu
$ g++ -c add.cpp
$ g++ -o test kernel.o add.o -L/usr/local/cuda/lib64 -lcudart
$ ./test

cmake编译就不讲了
结果如下:

./Cpp_rungpu
CPU time use is 1.1e-05
GPU time use is 0.366504
sum finish !!!

明显CPU时间短啦,,懂的都懂,为什么自己想想或者查查吧。

CudaFFT与FFTW对比

我装的是double的FFTW,FFTw这个很好装的啦,自己找找就好啦,装好后记得刷新(ldconfig)一下才可用哦。
cuda还有个cudafftw不是很清楚怎么用
文件

  1. main.cpp
  2. fftw_test.cpp
  3. fftw_test.h
  4. fft_cuda.cu
  5. fftw_cuda.cuh
  6. CMakeLists.txt

main.cpp

#include <iostream>
#include <fstream>
#include "fftw_test.h"
#include "fftw3.h"
#include "math.h"
using namespace std;//现在计算机安装的是double版本的fftw
int main()
{cout << "hello world !!!" << endl;clock_t time_used;clock_t start = clock();// data genlong int i;double Data[numFFT] = {0};double fs = 1000000.000;//mpling frequency 1E6double f0 = 200000.00;// signal frequency f 200kfor (i = 0; i < numFFT; i++){Data[i] = 1.35 * cos(2 * pi * f0 * i / fs);//signal gen,}complex<double> *data_in;data_in = (complex<double>*)fftw_malloc(sizeof(complex<double>)* numFFT);         //分配内存/*FFT数据*/for (i = 0; i < numFFT; i++){data_in[i] = complex<double>(Data[i],0);}cout << "----------********************--------" << endl;cout << "data generate time use is " <<  (clock() - start)*1.0/CLOCKS_PER_SEC << endl;start = clock();//cpu resultfftw_cpu *fft_cpu_test;fft_cpu_test = new fftw_cpu();cout << "build cpu class fft time use is " <<  (clock() - start)*1.0/CLOCKS_PER_SEC << endl;start = clock();fft_cpu_test->fftw_cpu_deal(data_in);cout << "CPU FFT time use is " <<  (clock() - start)*1.0/CLOCKS_PER_SEC << endl;cout << "----------********************--------" << endl;start = clock();//gpu resultfft_gpu *fft_gpu_test;fft_gpu_test = new fft_gpu(numFFT);cout << "build gpu class fft time use is " <<  (clock() - start)*1.0/CLOCKS_PER_SEC << endl;start = clock();fft_gpu_test->fft_gpu_deal(data_in,numFFT);cout << "GPU FFT time use is " <<  (clock() - start)*1.0/CLOCKS_PER_SEC << endl;cout << "----------********************--------" << endl;return 0;
}

fftw_test.cpp

#include "fftw_test.h"/*** cpu* */
fftw_cpu::fftw_cpu()
{//分配内存FFT_in = (fftw_complex*)fftw_malloc(sizeof(fftw_complex)* numFFT);FFT_out = (fftw_complex*)fftw_malloc(sizeof(fftw_complex)* numFFT);// long int i;// //不需要初始化     // for (i = 0; i < numFFT; i++)// {//     FFT_in[i][0] = 0.0;//  FFT_in[i][1] = 0.0;//  FFT_out[i][0] = 0.0;//     FFT_out[i][1] = 0.0;// }//C2C fft 创建FFT变换方案FFT_p = fftw_plan_dft_1d(numFFT, FFT_in,FFT_out, FFTW_FORWARD, FFTW_MEASURE);
}fftw_cpu::~fftw_cpu()
{//取消前面创建的FFT变换方案fftw_destroy_plan(FFT_p);//释放内存fftw_free(FFT_in);fftw_free(FFT_out);
}void fftw_cpu::fftw_cpu_deal(complex<double> *data)
{long int i;for (i = 0; i < numFFT; i++){FFT_in[i][0] = real(data[i]);FFT_in[i][1] = imag(data[i]);}fftw_execute(FFT_p);
}

fftw_test.h

#pragma once
#include "fftw3.h"
#include "fft_cuda.cuh"
#include <complex>
#include <iostream>
using namespace std;
#define numFFT 1000000
#define pi 3.1415926535
class fftw_cpu
{public:fftw_cpu();~fftw_cpu();private:fftw_complex *FFT_in;            //FFT 变换输入数据fftw_complex *FFT_out;          //FFT 变换输出数据fftw_plan FFT_p;                    //FFT 变换方案public:void fftw_cpu_deal(complex<double> *data);};

fft_cuda.cu

#include "fft_cuda.cuh"
/*
* gpu
*/
fft_gpu::fft_gpu(long int nFFT)
{//分配内存cudaMalloc((void**)&FFT_in, nFFT * sizeof(cufftComplex));// allocate memory for the data in devicecudaMalloc((void**)&FFT_out, nFFT * sizeof(cufftComplex));// allocate memory for the data in devicecufftPlan1d(&plan, nFFT, CUFFT_C2C, 1);//declaration first waste manytime
}
fft_gpu::~fft_gpu()
{cudaFree(FFT_in);cudaFree(FFT_out);cufftDestroy(plan);
}
/*
* complex 2 complex fft
*/
void fft_gpu::cufft_c2c(cufftComplex *FFT_in,cufftComplex *FFT_out,long int nFFT)
{cufftExecC2C(plan, (cufftComplex*)FFT_in, (cufftComplex*)FFT_out, CUFFT_FORWARD);//executecudaDeviceSynchronize();//wait to be done
}void fft_gpu::fft_gpu_deal(complex<double> *data,long int nFFT)
{long int i;cufftComplex* CompData = (cufftComplex*)malloc(nFFT * sizeof(cufftComplex));//allocate memory for the data in hostfor (i = 0; i < nFFT; i++){CompData[i].x = real(data[i]);CompData[i].y = imag(data[i]);}cudaMemcpy(FFT_in, CompData, nFFT * sizeof(cufftComplex), cudaMemcpyHostToDevice);// copy data from host to devicecufft_c2c(FFT_in,FFT_out,nFFT);
}

fft_cuda.cuh

#pragma once
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <stdio.h>
#include <cufft.h>
#include <complex>
using namespace std;
class fft_gpu
{public:fft_gpu(long int nFFT);~fft_gpu();private:cufftHandle plan;// cuda library function handle    cufftComplex *FFT_in;         //FFT 变换输入数据cufftComplex *FFT_out;          //FFT 变换输出数据void cufft_c2c(cufftComplex *FFT_in,cufftComplex *FFT_out,long int nFFT);public:void fft_gpu_deal(complex<double> *data,long int nFFT);};

CMakeLists.txt

cmake_minimum_required (VERSION 2.8)
project  (cudaFFT)
#significant note: gcc version 5.4.0
set(CMAKE_CXX_FLAGS "-std=c++11 -DNDEBUG -O2 ") ##-g find_package(CUDA QUIET REQUIRED)
include_directories("${CUDA_INCLUDE_DIRS}")include_directories(/usr/local/include)
link_directories(/usr/local/cuda/lib64)#fftw
find_package(FFTW3 REQUIRED)
include_directories(${FFTW3_INCLUDE_DIRS})
link_directories(/usr/local/lib)
message(${FFTW3_LIBRARIES})# cuda_add_executable(cudaFFT fft_cuda.cu )  ##关键语句
cuda_add_executable(cudaFFT main.cpp fftw_test.cpp fft_cuda.cu)
target_link_libraries(cudaFFT libcufft.so -lfftw3 ${FFTW3_LIBRARIES})

测试结果

$ cmake ..
$ make -j16
$ ./cudaFFT
hello world !!!
----------********************--------
data generate time use is 0.019092
build cpu class fft time use is 3.56016
CPU FFT time use is 0.020176
----------********************--------
build gpu class fft time use is 0.194864
GPU FFT time use is 0.00358
----------********************--------

两者的计算结果差异我还没来的急对比

需要注意的一点是,初始化的时间,fftw特别长,cudafft明显要快很多,当然这个一般不会太过于考虑啦,主要考试的时间是处理时间。从结果来看,gpu的时间大概是cpu的1/6,也就意味着GPU的执行效率比cpu高6倍

后面的工作主要还是要深入了解它的并行机制,以及数据传输。CPU->GPU-CPU,如何实现高效快速的并行处理,是一个值得探讨的问题。毕竟FFT只是调用库,grid,block, thread怎么分配,怎么实现都不用自己考虑。

linux-deepin-GPU-CudaFFT从入门到使用三天相关推荐

  1. caffe linux 教程,Caffe 深度学习入门教程 - 安装配置Ubuntu14.04+CUDA7.5+Caffe+cuDNN_Linux教程_Linux公社-Linux系统门户网站...

    安装配置Ubuntu14.04+CUDA7.5+Caffe+cuDNN 一.版本 Linux系统:Ubuntu 14.04 (64位) 显卡:Nvidia K20c cuda: cuda_7.5.18 ...

  2. Android/Linux 子系统Graphics图形栈入门普法介绍

        Android/Linux 子系统Graphics图形栈入门普法介绍 写在最前面   由于工作原因,最近在公司做了一个关于Android/Linux 子系统Graphics图形栈入门相关知识的 ...

  3. linux深度定制,Linux Deepin 12.06 beta1 发布

    反馈如下: 1) Linux Deepin 12.06 beta1 中文简体和繁体版本,默认安装后,主题有点问题,即默认的Metacity左上角的菜单背景色与文字的颜色都是白色,只有鼠标移经过时高亮才 ...

  4. 深度Linux13,Ubuntu 13.04安装Linux Deepin特色软件

    最新版本的 Linux Deepin 12.12 RC 已经将基础仓库升级到了 Ubuntu Raring,Linux Deepin 开发的特色软件,简单易用,其他发行版本的开发者应该尽量移植.因为 ...

  5. 深度linux12,Linux Deepin 12.06 试用体验

    新版本Linux Deepin 12.06 发布了,忍不住又试用了一把,把感触说一下与大家共享,Deepin 12.06 有很大提升,界面简洁漂亮,很多之前的问题得到解决,用户体验提升,即使是级别的用 ...

  6. linux深度定制,专为国人订制!Linux Deepin新版发布

    2011年终,深受国人喜爱的的深度Linux操作系统又发布新版本了,此次发布的是正式版Linux Deepin 11.12.从Linux Deepin 10.12版本开始,深度Linux采用了Gnom ...

  7. 王勇详谈 Linux Deepin 背后的故事

    (Linux Deepin最近发布了12.12版本.其也许是国内第一款比较优秀的桌面Linux系统.在此向致力于研发国产OS系统的猿人们表示敬意.虽然Deepin只是基于Ubuntu在桌面应用和UI方 ...

  8. linux windows主题下载官网,Linux Deepin 15.10.2 桌面kwin主题App美化

    前言 本人Linux小白,目前用的主力开发环境就是笔记本的Linux Deepin 最近想找Deepin桌面美化的方法 在商店评论里看到大神的这段评论,就打算实践一下学习学习本主题是gtk主题.所以只 ...

  9. 深度linux引导安装,全程演示Linux Deepin 12.06安装过程

    1为Deepin分配内存和磁盘资源 最近经常听到有网友讨论,当他们最喜爱的Windows XP在2014年官方停止补丁和安全更新之后,下一步该如何选择操作系统呢?选择市场占有率直线攀升的Windows ...

  10. ubuntu安装linux deepin,如何在Ubuntu中安装Deepin终端 | MOS86

    Deepin终端是一个基于python的终端仿真器,专为中国Linux发行版开发,名为"Deepin"."它有许多有用的功能,其中一些,如"地震模式" ...

最新文章

  1. 【java】maven工程使用switch时不能使用String解决方法
  2. Java基础篇:泛型
  3. 中了logo1.exe
  4. Win8/Win8.1常见错误代码的解决方法汇总
  5. uboot 命令分析(一) — bootm
  6. 在Windows XP 中使用Active Directory(活动目录)
  7. python 在数字前面自动补0
  8. 1006. 换个格式输出整数 (15)
  9. WebSSH2安装过程可实现WEB可视化管理SSH工具
  10. 方案改进:直接通过User Control生成HTML
  11. Docker简介和安装
  12. linux编程基础黑马要点总结,黑马《linux基础编程》学习笔记(从6到10)
  13. 初识C语言学习笔记 入门
  14. 关于python的文献综述_什么是论文文献综述
  15. 业务分析师Business Analysist(BA)的职业发展之路
  16. html5如何设置视频为静音,html5中设置或返回音频/视频是否应该被静音的属性muted-...
  17. comon lisp标准_common Lisp学习笔记(十四)
  18. ZigBee自组网地址分配与路由协议技术详解
  19. 【计算机毕业设计】018实习记录
  20. WebGL和OpenGL的区别及关系

热门文章

  1. flask 本地局域网连接
  2. android直播聊天室图文混排效果,仿抖音直播聊天室换行内容TextView+ReplacementSpan...
  3. 佛教与人生(了解学习佛法的科普文章)
  4. kdevelop怎么调试_使用Kdevelop4调试ns
  5. 【koa2】创建项目
  6. Bezier曲线 OpenCV
  7. 【面经——《速腾聚创科技有限公司——深度学习算法工程师》】
  8. 《贝叶斯思维:统计建模的Python学习法》——1.3 曲奇饼问题
  9. Android 添加、移除桌面快捷方式图标
  10. 【LeetCode】【有效的括号】