(二)了解CPU、GPU、进程、线程、CUDA

GPU和CPU的区别是什么?

CPU是中央处理器,GPU是图形处理器
不同点:
CPU虽然有多核,但总数<100,每个核都有足够大的缓存和足够多的数字和逻辑运算单元。擅长处理具有复杂计算步骤和复杂数据依赖的计算任务,如分布式计算,数据压缩,人工智能,物理模拟。
GPU的核数远超CPU。每个核拥有的缓存大小相对小,数字逻辑运算单元也少而且简单。主要是用于对海量数据进行相同的操作,如:对每一个顶点进行同样的坐标变换。应用如数值分析,海量数据处理。
简言之:CPU统筹协调,GPU处理海量数据

进程和线程的区别?

进程是可以独立运行的程序
线程是执行进程中的路径
关系:
1.一个线程只能属于一个进程,而一个进程可以有多个线程。
2.线程是指进程内的一个执行单元,也是进程内的可调度实体。

什么是CUDA?

CUDA(Compute Unified Device Architecture),是显卡厂商NVIDIA推出的运算平台。它是一种并行计算架构,该架构能使GPU能够解决复杂的计算问题。支持的语言是C语言,CUDA3.0已经开始支持C++和FORTRAN。
简言之:CUDA是一种架构,让GPU进行并行计算。

使用CUDA的一般步骤?

  1. 设置设备
  2. 分配显存空间
  3. 将宿主程序数据复制到显存中
  4. 执行程序,宿主程序等待显卡执行完毕
  5. 与内核同步等待执行完毕
  6. 获取数据

一个CUDA程序例子?

#include <cuda_runtime.h>  
#include <stdio.h>  

__global__ void addKernel( int* c, constint* a, const int* b )  
{  
         inti = threadIdx.x;  
         c[i]= a[i] + b[i];  
}  

cudaError_t CUDA_Add( const int* a, constint* b, int* out, int size )  
{  
         int*dev_a;  
         int*dev_b;  
         int*dev_c;  

         //1、设置设备  
         cudaError_tcudaStatus = cudaSetDevice( 0 );  

         switch( true )  
         {  
         default:  
                   if( cudaStatus != cudaSuccess )  
                   {  
                            fprintf(stderr, "调用cudaSetDevice()函数失败!" );  
                            returncudaStatus;  
                   }  

                   //2、分配显存空间  
                   cudaStatus= cudaMalloc( (void**)&dev_a, size * sizeof(int) );  
                   if( cudaStatus != cudaSuccess )  
                   {  
                            fprintf(stderr, "调用cudaMalloc()函数初始化显卡中a数组时失败!" );  
                            break;  
                   }  

                   cudaStatus= cudaMalloc( (void**)&dev_b, size * sizeof(int) );  
                   if( cudaStatus != cudaSuccess )  
                   {  
                            fprintf(stderr, "调用cudaMalloc()函数初始化显卡中b数组时失败!" );  
                            break;  
                   }  

                   cudaStatus= cudaMalloc( (void**)&dev_c, size * sizeof(int) );  
                   if( cudaStatus != cudaSuccess )  
                   {  
                            fprintf(stderr, "调用cudaMalloc()函数初始化显卡中c数组时失败!" );  
                            break;  
                   }  

                   //3、将宿主程序数据复制到显存中  
                   cudaStatus= cudaMemcpy( dev_a, a, size * sizeof( int ), cudaMemcpyHostToDevice );  
                   if( cudaStatus != cudaSuccess )  
                   {  
                            fprintf( stderr, "调用cudaMemcpy()函数初始化宿主程序数据a数组到显卡时失败!");  
                            break;  
                   }  
                   cudaStatus= cudaMemcpy( dev_b, b, size * sizeof( int ), cudaMemcpyHostToDevice );  
                   if( cudaStatus != cudaSuccess )  
                   {  
                            fprintf(stderr, "调用cudaMemcpy()函数初始化宿主程序数据b数组到显卡时失败!" );  
                            break;  
                   }  

                   //4、执行程序,宿主程序等待显卡执行完毕  
                   addKernel<<<1,size>>>( dev_c, dev_a, dev_b );  

                   //5、查询内核初始化的时候是否出错  
                   cudaStatus= cudaGetLastError( );  
                   if( cudaStatus != cudaSuccess )  
                   {  
                            fprintf(stderr, "显卡执行程序时失败!" );  
                            break;  
                   }  

                   //6、与内核同步等待执行完毕  
                   cudaStatus= cudaDeviceSynchronize( );  
                   if( cudaStatus != cudaSuccess )  
                   {  
                            fprintf(stderr, "在与内核同步的过程中发生问题!" );  
                            break;  
                   }  

                   //7、获取数据  
                   cudaStatus= cudaMemcpy( out, dev_c, size * sizeof( int ), cudaMemcpyDeviceToHost );  
                   if( cudaStatus != cudaSuccess )  
                   {  
                            fprintf(stderr, "在将结果数据从显卡复制到宿主程序中失败!" );  
                            break;  
                   }  
         }  

         cudaFree(dev_c );  
         cudaFree(dev_a );  
         cudaFree(dev_b );  

         returncudaStatus;  
}  

int main( int argc, char** argv )  
{  
         constint arraySize = 5;  
         constint a[arraySize] = { 1, 2, 3, 4, 5 };  
         constint b[arraySize] = { 10, 20, 30, 40, 50 };  
         intc[arraySize] = { 0 };  

         cudaError_tcudaStatus;  

         cudaStatus= CUDA_Add( a, b, c, arraySize );  

         printf("运算结果是:\nc数组[%d, %d, %d, %d, %d]\n",  
                   c[0],c[1], c[2], c[3], c[4] );  

         cudaStatus= cudaDeviceReset( );  
         if( cudaStatus != cudaSuccess )  
         {  
                   fprintf(stderr, "调用cudaDeviceReset()函数失败!" );  
                   return1;  
         }  

         return0;  
}  

//可以看出,CUDA程序和C程序并无区别,只是多了一些以”cuda”开头的一些库函数。

这里写图片描述


注:本文信息大多是个人见解,并且来自网络。参考的是知乎,CSDN。

猜你喜欢

转载自blog.csdn.net/lemon4869/article/details/53415734