日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

OpenCL “速成”冲刺【第一天】

發布時間:2023/12/18 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 OpenCL “速成”冲刺【第一天】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

話說軟件開發從來沒有速成一說,一門語言你學的越快,說明你在別的語言上下個功夫越多,所以這次加了引號,只不過幾周之后可能會有一個公司內部OpenCL的考核,雖然本人不需要考核,不過也正好借機整理下之前OpenCL的經驗,一方面幫著下別的同事,一方面也給自己留點干活。這個教程針對有一點C/C++開發經驗的童鞋,如果沒有太多經驗,我建議還是先去學學C語言。


這個是wiki上OpenCL的定義,我感覺想學OpenCL的人應該都已經知道了。

OpenCL?(Open?Computing?Language,開放計算語言) 是一個為異構平臺編寫程序的框架,此異構平臺可由CPU,GPU或其他類型的處理器組成。OpenCL由一門用于編寫kernels (在OpenCL設備上運行的函數)的語言(基于C99)和一組用于定義并控制平臺的API組成。OpenCL提供了基于任務分割和數據分割的并行計算機制。


第一天,環境,項目,HelloWorld


硬件環境

你需要一臺支持OpenCL的設備,AMD,Nvidia的顯卡,Intel的CPU(最好帶核顯),型號不能太老了,3年內的基本沒問題。

本次教程將以Intel的CPU配合AMD的顯卡為例。


軟件環境

操作系統是windows的,下載安裝AMDAPPSDK for windows,VS2012(老版本也行,我推薦用新的)。

操作系統是linux的,下載安裝AMDAPPSDK for linux,Code::blocks(喜歡VIM的也行,或者說更好)。

下載自己常用的版本控制軟件,和C/C++輔助開發軟件。

PS:OpenCL也就是庫和頭文件,各個廠商的SDK也就是OpenCL+Tools+Samples,別的廠商也有相應的SDK,百度“廠商 OpenCL SDK"的關鍵字組合都能找到。


檢測開發環境

安裝好AMDAPPSDK之后,在命令行下運行clinfo命令,將顯示出你支持OpenCL的硬件信息。

PS:不是AMD的設備,可以用CPUz,GPUz等軟件查詢是否支持OpenCL。


配置項目

個人認為,既然你已經知道了OpenCL就是庫那么應該知道怎么配置項目,否則可能就是不滿足有一點C/C++開發經驗這個前提了。不過為了方便,還是貼出來。

自己去安裝軟件的目錄下找到OpenCL庫文件的位置(一般是C:\Program Files (x86)\AMD APP),linux直接find -name ”opencl“ 命令就行(一般在/opt/AMDAPP下)。

Visual Studio系列(別用VC6,不解釋)

項目屬性->C++->常規->附加包含目錄,把SDK下邊的include目錄加進去。

項目屬性->鏈接器->常規->附加庫目錄,把SDK下邊的lib/x86_64(x64)目錄加進去。

項目屬性->鏈接器->輸入->附加依賴項,輸入opencl.lib

PS: 安裝完SDK,一般會在系統中加入環境變量的,用環境變量配置上邊的路徑更方便,比如$(AMDAPPSDKROOT)include就解決了,這樣換了電腦的話,只要是相同廠商就能通用。

Code::blocks

右鍵項目->Properties...->Project's build options,輸入下邊內容

-I/opt/AMDAPP/include ?-L/opt/AMDAPP/lib/x86_64 ?-lOpenCL?

PS: 其實OpenCL就是配置好頭文件和庫文件,直接粘貼到項目中也行,但是不推薦,換個電腦可能就不好使了。


HelloWorld

本人偷懶就用fixstar的代碼了,建立項目,新建c或者cpp文件,粘貼下列代碼進去:

[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;??
  • ??
  • ????/*?Load?the?source?code?containing?the?kernel*/??
  • ????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);??
  • ??
  • ????/*?Get?Platform?and?Device?Info?*/??
  • ????ret?=?clGetPlatformIDs(1,?&platform_id,?&ret_num_platforms);??
  • ????ret?=?clGetDeviceIDs(platform_id,?CL_DEVICE_TYPE_DEFAULT,?1,?&device_id,?&ret_num_devices);??
  • ??
  • ????/*?Create?OpenCL?context?*/??
  • ????context?=?clCreateContext(NULL,?1,?&device_id,?NULL,?NULL,?&ret);??
  • ??
  • ????/*?Create?Command?Queue?*/??
  • ????command_queue?=?clCreateCommandQueue(context,?device_id,?0,?&ret);??
  • ??
  • ????/*?Create?Memory?Buffer?*/??
  • ????memobj?=?clCreateBuffer(context,?CL_MEM_READ_WRITE,MEM_SIZE?*?sizeof(char),?NULL,?&ret);??
  • ????/*?Create?Kernel?Program?from?the?source?*/??
  • ????program?=?clCreateProgramWithSource(context,?1,?(const?char?**)&source_str,(const?size_t?*)&source_size,?&ret);??
  • ??
  • ????/*?Build?Kernel?Program?*/??
  • ????ret?=?clBuildProgram(program,?1,?&device_id,?NULL,?NULL,?NULL);??
  • ??
  • ????/*?Create?OpenCL?Kernel?*/??
  • ????kernel?=?clCreateKernel(program,?"hello",?&ret);??
  • ??
  • ????/*?Set?OpenCL?Kernel?Parameters?*/??
  • ????ret?=?clSetKernelArg(kernel,?0,?sizeof(cl_mem),?(void?*)&memobj);??
  • ??
  • ????/*?Execute?OpenCL?Kernel?*/??
  • ????ret?=?clEnqueueTask(command_queue,?kernel,?0,?NULL,NULL);??
  • ??
  • ????/*?Copy?results?from?the?memory?buffer?*/??
  • ????ret?=?clEnqueueReadBuffer(command_queue,?memobj,?CL_TRUE,?0,??
  • ????????MEM_SIZE?*?sizeof(char),string,?0,?NULL,?NULL);??
  • ??
  • ????/*?Display?Result?*/??
  • ????puts(string);??
  • ??
  • ????/*?Finalization?*/??
  • ????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,粘貼下列代碼進去: [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';??
  • }??

  • 編譯執行文件。


    第一天的內容就是這些,明天將講解上邊的代碼和OpenCL的組織結構。


    作業:閱讀上邊的代碼,解釋各個API的含義,寫上中文注釋(最好別直接翻譯),將代碼上傳到自己的版本管理工具上。


    總結

    以上是生活随笔為你收集整理的OpenCL “速成”冲刺【第一天】的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。