OpenCL入門程式

2021-06-27 15:03:52 字數 3543 閱讀 3950

注意:  

如果是從視訊記憶體到視訊記憶體不是用writebuffer而是用copybuffer

以前就聽說opencl,今天就特地使用了一下,我的機器是n卡,首先裝上了cuda的開發包,由於cuda對opencl支援比較好,就選擇了n卡上的gpu平行計算。

opencl是乙個開放的標準和規範,全程是開放計算庫,主要是發揮計算機的所有計算資源,包括cpu、gpu、多核等。所以說opencl是乙個跨硬體和軟體平台的開放標準,在此框架下開發的平行計算程式很容易就能移植到其他平台上,也許是這樣吧。其實,關於gpu的平行計算的大致思路一般都是cpu向gpu傳送乙個計算指令,然後把資料拷貝的gpu的視訊記憶體中參與計算,然後將計算好的視訊記憶體中的資料拷貝到主機記憶體中,雖然說,過程大概就是這樣,但是其中涉及到的細節可是特別多。下面就以乙個簡單的例子為例講述opencl程式設計開發的一般步驟和模型。

第一步,首先獲得可以參與計算的opencl平台個數

cl_uint numplatforms = 0;   //gpu計算平台個數

cl_platform_id platform = null;

clgetplatformids(0,null,&numplatforms);

第二步,獲得平台的列表,並選擇其中的乙個作為計算的平台  

//獲得平台列表

cl_platform_id * platforms = (cl_platform_id*)malloc(numplatforms * sizeof(cl_platform_id));

clgetplatformids (numplatforms, platforms, null);

//輪詢各個opencl裝置

for (cl_uint i = 0; i < numplatforms; i ++)

free(platforms);

第三步,獲得硬體裝置以及生成上下文  

//獲得gpu裝置

cl_device_id device;

status = clgetdeviceids(platform, cl_device_type_gpu, 1, &device, null);

//生成上下文

cl_context context = clcreatecontext(0, 1, &device, null, null, &status);

至此,opencl的初始化工作已經完成,最好將這個過程封裝成乙個函式。  

第四步,裝載核心程式**以及生成program

//裝載核心程式

size_t szkernellength = 0;

size_t sourcesize = ;

char *cfilename = "kernel.cl";

char * cpathandname= shrfindfilepath(cfilename, argv[0]);

const

char* kernelsourcecode = oclloadprogsource(cpathandname, "", &szkernellength);

cl_program program = clcreateprogramwithsource(context,1,&kernelsourcecode,&szkernellength,&status);

//為所有指定的裝置生成cl_program

status = clbuildprogram(program,1,&device,null,null,null);

size_t len = 0;

char buf[2048];

if (status != cl_success)

第五步,建立乙個命令佇列,將這個命令佇列放入核心程式中執行  

//建立乙個opencl命令佇列

cl_command_queue commandqueue = clcreatecommandqueue(context,device,0,&status);

//建立opencl buffer物件

cl_mem outputbuffer = clcreatebuffer(context,cl_mem_alloc_host_ptr,4*4*4,null,&status);

//得到指定名字的核心例項控制代碼

cl_kernel kernel = clcreatekernel(program,"hellocl",&status);

//為核心程式設定相應的引數,也就是函式傳參

status = clsetkernelarg(kernel,0,sizeof(cl_mem),&outputbuffer);

//將乙個kernel放入佇列

size_t globalthreads = ;

size_t localthreads = ;

//開始在裝置上執行核函式

status = clenqueuendrangekernel(commandqueue,kernel,2,null,

globalthreads,localthreads,0,null,null);

status = clfinish(commandqueue);

第六步,將計算結果拷貝到主存中  

//將gpu本地記憶體中的資料拷回到host端的記憶體中

unsigned

int *outbuffer = new

unsigned

int[4*4];

memset(outbuffer,0,4*4*4);

status = clenqueuereadbuffer(commandqueue,outputbuffer,

cl_true,0,4*4*4,outbuffer,0,null,null);

第七步,顯示及清理記憶體  

printf("out:\n");

for (int i = 0; i < 16; i ++)

}//清理部分

status = clreleasekernel(kernel);

status = clreleaseprogram(program);

status = clreleasememobject(outputbuffer);

status = clreleasecommandqueue(commandqueue);

status = clreleasecontext(context);

delete

outbuffer;

核函式如下:

__kernel void hellocl (__global uint *buffer)

else

if(dim == 2)

else

}

運算結果顯示如下圖:  

這只是最簡單的程式,複雜演算法的並行化還需要深入研究。

opencl入門程式

今天搞了很久opencl上手真的很麻煩,主要覺得是開發的平台相關性比較強吧。不對請指正 網上搞了幾個門程式,居然有錯不能執行,也太不負責任了吧,至少能編譯通過才拿出來啊,少個括號什麼的,太不厚道 以下公布我修改過的入門程式 系統庫 include stdafx.h include include o...

OpenCL入門概念

opencl將cpu和gpu組合利用起來做並構運算 gpu的優勢在於同時進行多個運算 for int i 0 i 5 i do some thing cpu執行以上迴圈的實現是序列運算5次 順序是012 34gpu執行以上迴圈的實現是並行運算一次 同時執行012 34和opengl的原理有些類似 o...

高效能計算 OpenCL入門1

獲取平台資料 void getplatforminfo 建立平台 建立裝置 根據裝置建立上下文 cl context createcontext cl device id device if errnum cl success if errnum cl success clgetdeviceids ...