生活随笔
收集整理的這篇文章主要介紹了
OpenCL “速成”冲刺【第一天】
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
話說軟件開發(fā)從來沒有速成一說,一門語言你學(xué)的越快,說明你在別的語言上下個(gè)功夫越多,所以這次加了引號(hào),只不過幾周之后可能會(huì)有一個(gè)公司內(nèi)部OpenCL的考核,雖然本人不需要考核,不過也正好借機(jī)整理下之前OpenCL的經(jīng)驗(yàn),一方面幫著下別的同事,一方面也給自己留點(diǎn)干活。這個(gè)教程針對(duì)有一點(diǎn)C/C++開發(fā)經(jīng)驗(yàn)的童鞋,如果沒有太多經(jīng)驗(yàn),我建議還是先去學(xué)學(xué)C語言。
這個(gè)是wiki上OpenCL的定義,我感覺想學(xué)OpenCL的人應(yīng)該都已經(jīng)知道了。
OpenCL?(Open?Computing?Language,開放計(jì)算語言) 是一個(gè)為異構(gòu)平臺(tái)編寫程序的框架,此異構(gòu)平臺(tái)可由CPU,GPU或其他類型的處理器組成。OpenCL由一門用于編寫kernels (在OpenCL設(shè)備上運(yùn)行的函數(shù))的語言(基于C99)和一組用于定義并控制平臺(tái)的API組成。OpenCL提供了基于任務(wù)分割和數(shù)據(jù)分割的并行計(jì)算機(jī)制。
第一天,環(huán)境,項(xiàng)目,HelloWorld
硬件環(huán)境
你需要一臺(tái)支持OpenCL的設(shè)備,AMD,Nvidia的顯卡,Intel的CPU(最好帶核顯),型號(hào)不能太老了,3年內(nèi)的基本沒問題。
本次教程將以Intel的CPU配合AMD的顯卡為例。
軟件環(huán)境
操作系統(tǒng)是windows的,下載安裝AMDAPPSDK for windows,VS2012(老版本也行,我推薦用新的)。
操作系統(tǒng)是linux的,下載安裝AMDAPPSDK for linux,Code::blocks(喜歡VIM的也行,或者說更好)。
下載自己常用的版本控制軟件,和C/C++輔助開發(fā)軟件。
PS:OpenCL也就是庫(kù)和頭文件,各個(gè)廠商的SDK也就是OpenCL+Tools+Samples,別的廠商也有相應(yīng)的SDK,百度“廠商 OpenCL SDK"的關(guān)鍵字組合都能找到。
檢測(cè)開發(fā)環(huán)境
安裝好AMDAPPSDK之后,在命令行下運(yùn)行clinfo命令,將顯示出你支持OpenCL的硬件信息。
PS:不是AMD的設(shè)備,可以用CPUz,GPUz等軟件查詢是否支持OpenCL。
配置項(xiàng)目
個(gè)人認(rèn)為,既然你已經(jīng)知道了OpenCL就是庫(kù)那么應(yīng)該知道怎么配置項(xiàng)目,否則可能就是不滿足有一點(diǎn)C/C++開發(fā)經(jīng)驗(yàn)這個(gè)前提了。不過為了方便,還是貼出來。
自己去安裝軟件的目錄下找到OpenCL庫(kù)文件的位置(一般是C:\Program Files (x86)\AMD APP),linux直接find -name ”opencl“ 命令就行(一般在/opt/AMDAPP下)。
Visual Studio系列(別用VC6,不解釋)
項(xiàng)目屬性->C++->常規(guī)->附加包含目錄,把SDK下邊的include目錄加進(jìn)去。
項(xiàng)目屬性->鏈接器->常規(guī)->附加庫(kù)目錄,把SDK下邊的lib/x86_64(x64)目錄加進(jìn)去。
項(xiàng)目屬性->鏈接器->輸入->附加依賴項(xiàng),輸入opencl.lib
PS: 安裝完SDK,一般會(huì)在系統(tǒng)中加入環(huán)境變量的,用環(huán)境變量配置上邊的路徑更方便,比如$(AMDAPPSDKROOT)include就解決了,這樣換了電腦的話,只要是相同廠商就能通用。
Code::blocks
右鍵項(xiàng)目->Properties...->Project's build options,輸入下邊內(nèi)容
-I/opt/AMDAPP/include ?-L/opt/AMDAPP/lib/x86_64 ?-lOpenCL?
PS: 其實(shí)OpenCL就是配置好頭文件和庫(kù)文件,直接粘貼到項(xiàng)目中也行,但是不推薦,換個(gè)電腦可能就不好使了。
HelloWorld
本人偷懶就用fixstar的代碼了,建立項(xiàng)目,新建c或者cpp文件,粘貼下列代碼進(jìn)去:
[cpp] view plaincopyprint?
#include?<stdio.h>??#include?<stdlib.h>??#include?<CL/cl.h>????#define?MEM_SIZE?(128)??#define?MAX_SOURCE_SIZE?(0x100000)????int?main()??{??????cl_device_id?device_id?=?NULL;??????cl_context?context?=?NULL;??????cl_command_queue?command_queue?=?NULL;??????cl_mem?memobj?=?NULL;??????cl_program?program?=?NULL;??????cl_kernel?kernel?=?NULL;??????cl_platform_id?platform_id?=?NULL;??????cl_uint?ret_num_devices;??????cl_uint?ret_num_platforms;??????cl_int?ret;????????char?string[MEM_SIZE];????????FILE?*fp;??????char?fileName[]?=?"./main.cl";??????char?*source_str;??????size_t?source_size;??????????????fp?=?fopen(fileName,?"r");??????if?(!fp)?{??????????fprintf(stderr,?"Failed?to?load?kernel.\n");??????????exit(1);??????}??????source_str?=?(char*)malloc(MAX_SOURCE_SIZE);??????source_size?=?fread(source_str,?1,?MAX_SOURCE_SIZE,?fp);??????fclose(fp);??????????????ret?=?clGetPlatformIDs(1,?&platform_id,?&ret_num_platforms);??????ret?=?clGetDeviceIDs(platform_id,?CL_DEVICE_TYPE_DEFAULT,?1,?&device_id,?&ret_num_devices);??????????????context?=?clCreateContext(NULL,?1,?&device_id,?NULL,?NULL,?&ret);??????????????command_queue?=?clCreateCommandQueue(context,?device_id,?0,?&ret);??????????????memobj?=?clCreateBuffer(context,?CL_MEM_READ_WRITE,MEM_SIZE?*?sizeof(char),?NULL,?&ret);????????????program?=?clCreateProgramWithSource(context,?1,?(const?char?**)&source_str,(const?size_t?*)&source_size,?&ret);??????????????ret?=?clBuildProgram(program,?1,?&device_id,?NULL,?NULL,?NULL);??????????????kernel?=?clCreateKernel(program,?"hello",?&ret);??????????????ret?=?clSetKernelArg(kernel,?0,?sizeof(cl_mem),?(void?*)&memobj);??????????????ret?=?clEnqueueTask(command_queue,?kernel,?0,?NULL,NULL);??????????????ret?=?clEnqueueReadBuffer(command_queue,?memobj,?CL_TRUE,?0,??????????MEM_SIZE?*?sizeof(char),string,?0,?NULL,?NULL);??????????????puts(string);??????????????ret?=?clFlush(command_queue);??????ret?=?clFinish(command_queue);??????ret?=?clReleaseKernel(kernel);??????ret?=?clReleaseProgram(program);??????ret?=?clReleaseMemObject(memobj);??????ret?=?clReleaseCommandQueue(command_queue);??????ret?=?clReleaseContext(context);????????free(source_str);????????getchar();??????return?0;????}??
新建文件,后綴改成.cl,粘貼下列代碼進(jìn)去:
[cpp] view plaincopyprint?
__kernel?void?hello(__global?char*?string)??{??????string[0]?=?'H';??????string[1]?=?'e';??????string[2]?=?'l';??????string[3]?=?'l';??????string[4]?=?'o';??????string[5]?=?',';??????string[6]?=?'?';??????string[7]?=?'W';??????string[8]?=?'o';??????string[9]?=?'r';??????string[10]?=?'l';??????string[11]?=?'d';??????string[12]?=?'!';??????string[13]?=?'\0';??}??
編譯執(zhí)行文件。
第一天的內(nèi)容就是這些,明天將講解上邊的代碼和OpenCL的組織結(jié)構(gòu)。
作業(yè):閱讀上邊的代碼,解釋各個(gè)API的含義,寫上中文注釋(最好別直接翻譯),將代碼上傳到自己的版本管理工具上。
總結(jié)
以上是生活随笔為你收集整理的OpenCL “速成”冲刺【第一天】的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。