zoukankan      html  css  js  c++  java
  • 【CUDA】CUDA C入门、简单介绍

    CUDA编程注意事项

    CUDA中不能在主机代码中对cudaMalloc()返回的指针进行解引用。

    1. 可以将cudaMalloc()分配的指针传递给在设备上执行的函数。
    2. 可以在设备代码中使用cudaMalloc()分配的指针进行内存读/写操作。
    3. 可以将cudaMalloc()分配的指针传递给在主机上执行的函数。
    4. 不能在主机代码中使用cudaMalloc()分配的指针进行内存读/写操作。

    CUDA运行模式

    1. CPU传给GPU数据
    2. GPU计算
    3. GPU传给CPU结果

    详细一点:

    1. 给GPU设备分配内存
       cudaMalloc((void**)&dev_input, sizeof(int)));
    
       cudaMalloc((void**)&dev_result, sizeof(int)));
    
    1. 在CPU上为输入变量赋初值 input

    2. CPU将输入变量传递给GPU

       cudaMemcpy(dev_input, input, sizeof(int), cudaMemcpyHostToDevice);
    
    1. GPU对输入变量进行并行计算——核函数
       kernel_function<<<N,1>>>(dev_input, dev_result);
    

    其中,N表示设备在执行核函数时使用的并行线程块的数量。

    例如,若指定的事kernel<<<2,1>>>(),那么可以认为运行时将创建核函数的两个副本并且并行方式运行。每个并行执行环境就是一个线程块(Block)。而所有的并行线程块集合称为一个线程格(Grid)。另外注意,线程块数组每一维的最大数量都不能超过65535

    问题:如果在代码中知晓正在运行的是哪个线程块?

    答:利用内置变量blockIdx(二维索引)。例如:

       int tid = blockIdx.x;  //计算位于这个索引处的数据。
    
    1. GPU将计算结果传回给CPU
       cudaMemcpy(result, dev_result, sizeof(int), cudaMemcpyDeviceToHost);
    
    1. 释放在GPU上分配的内存
       cudaFree(dev_input); 
       cudaFree(dev_result);
    

    CUDA有趣示例

    下面放一个实例,是绘制Julia集曲线的例子,需要提前下载好一些cuda官方的头文件,链接在此。代码如下:

    #include "cuda_runtime.h"
    #include "device_launch_parameters.h"
    #include "D:Projects_CUDAcuda_by_examplecommoncpu_bitmap.h" //这里换成你自己的cuda_by_example路径
    #include "D:Projects_CUDAcuda_by_examplecommonook.h" //这里换成你自己的cuda_by_example路径
    #include <stdio.h>
    using namespace std;
    #define DIM 1000
    
    struct  cuComplex{
    	float r;
    	float i;
    	__device__ cuComplex(float a, float b){
    		r = a;
    		i = b;
    	}
    	__device__ float magnitude2(void) {
    		return r * r + i * i;
    	}
    
    	__device__ cuComplex operator * (const cuComplex& a){
    		return cuComplex(r*a.r - i*a.i, i*a.r + r*a.i);
    	}
    
    	__device__ cuComplex operator + (const cuComplex& a){
    		return cuComplex(r + a.r, i + a.i);
    	}
    };
    
    __device__ int julia(int x, int y){
    	const float scale = 1.5;
    	float jx = scale * (float)(DIM / 2 - x) / (DIM / 2);
    	float jy = scale * (float)(DIM / 2 - y) / (DIM / 2);
    
    	cuComplex c(-0.8, 0.156);
    	cuComplex a(jx, jy);
    
    	int i = 0;
    	for (i = 0; i < 200; i++){
    		a = a * a + c;
    		if (a.magnitude2() > 1000)
    			return 0;
    	}
    	return 1;
    }
    __global__ void kernel(unsigned char *ptr){
    	int x = blockIdx.x;
    	int y = blockIdx.y;
    	int offset = x + y * gridDim.x;
    
    	int juliaValue = julia(x, y);
    	ptr[offset * 4 + 0] = 255 * juliaValue;
    	ptr[offset * 4 + 1] = 0;
    	ptr[offset * 4 + 2] = 0;
    	ptr[offset * 4 + 3] = 255;
    }
    struct DataBlock {
    	unsigned char   *dev_bitmap;
    };
    int main(void){
    	CPUBitmap bitmap(DIM, DIM);
    	unsigned char *dev_bitmap;
    
    	HANDLE_ERROR(cudaMalloc((void**)&dev_bitmap, bitmap.image_size()));
    
    	dim3 grid(DIM, DIM);
    	kernel << <grid, 1 >> >(dev_bitmap);
    
    	HANDLE_ERROR(cudaMemcpy(bitmap.get_ptr(), dev_bitmap, bitmap.image_size(), cudaMemcpyDeviceToHost));
    
    	bitmap.display_and_exit();
    
    	HANDLE_ERROR(cudaFree(dev_bitmap));
    }
    

    运行结果(美炸了):

    julia

  • 相关阅读:
    团队项目的NABC(截图软件)
    《梦断代码》读后感_3
    《梦断代码》读后感_2
    毕设今日总结(二)
    毕业设计今日总结(一)
    QT中文乱码解决方法
    课堂练习——最大联通之数组
    《浪潮之巅》读书笔记3
    《浪潮之巅》读书笔记2
    《浪潮之巅》读书笔记1
  • 原文地址:https://www.cnblogs.com/hatimwen/p/cudac.html
Copyright © 2011-2022 走看看