clCreateBuffer第二個參數可以有多種,詳情請點擊此次,對於前三個比較簡單,在此就忽略。
1、CL_MEM_USE_HOST_PTR
對於CL_MEM_USE_HOST_PTR,剛開始buffer object的值是來自於host_ptr,但buffer object處理之後,host_ptr中的值如何變化,這點在OpenCL中沒有定義。那就看看A卡對次是如何處理,一個小程序:
data=new float[N];
output=new float[N];
for(int i=0;i<N;i++){
data[i]=1;
}
b=1;
...
bufferA=clCreateBuffer(context,CL_MEM_READ_ONLY|CL_MEM_USE_HOST_PTR,sizeof(float)*N,data,&err);
...
err=clEnqueueReadBuffer(cmdQueue,bufferA,CL_TRUE,0,sizeof(float)*N,output,0,NULL,&timing_event);
...
for(int i=0;i<N;i++){
cout<<"output:"<<output[i];
cout<<" data:"<<data[i]<<endl;
}
對於kernel函數:
__kernel void call_test(__global float* A,const float b)
{
int index=get_global_id(0);
A[index]=b+100;
}
程序執行結果如下:
output:101 data:101
output:101 data:101
output:101 data:101
output:101 data:101
output:101 data:101
output:101 data:101
output:101 data:101
output:101 data:101
output:101 data:101
output:101 data:101
output:101 data:101
output:101 data:101
output:101 data:101
output:101 data:101
output:101 data:101
output:101 data:101
output:101 data:101
可以出,對於A卡OpenCL實現來說,對於buffer object操作完之後的值,也寫回到host_ptr主機內存中。
2、CL_MEM_COPY_HOST_PTR
對於CL_MEM_COPY_HOST_PTR來說,buffer object的初始值使用host_ptr,buffer object操作完成後的值也不會寫回到host_ptr主機內存中。繼續看代碼:
(修改上述代碼創建buffer object代碼)
bufferA=clCreateBuffer(context,CL_MEM_READ_ONLY|CL_MEM_COPY_HOST_PTR,sizeof(float)*N,data,&err);
其他代碼保持不變,程序結果爲:
output:101 data:1
output:101 data:1
output:101 data:1
output:101 data:1
output:101 data:1
output:101 data:1
output:101 data:1
output:101 data:1
output:101 data:1
output:101 data:1
output:101 data:1
output:101 data:1
output:101 data:1
output:101 data:1
output:101 data:1
output:101 data:1
output:101 data:1
output:101 data:1
output:101 data:1
3、CL_MEM_USE_PERSISTENT_MEM_AMD
對於CL_MEM_USE_PERSISTENT_MEM_AMD,創建的buffer object是在設備內存上的zero copy buffer。對於CL_MEM_USE_PERSISTENT_MEM_AMD的使用,請看下列代碼:
bufferA=clCreateBuffer(context,CL_MEM_READ_ONLY|CL_MEM_USE_PERSISTENT_MEM_AMD,sizeof(float)*N,0,&err);
checkErr(err,"clCreateBuffer",__LINE__);
void *mapPtr=clEnqueueMapBuffer(cmdQueue,bufferA,CL_TRUE,CL_MAP_WRITE,0,sizeof(float)*N,0,NULL,NULL,&err);
memcpy(mapPtr,data,sizeof(float)*N);
err=clEnqueueUnmapMemObject(cmdQueue,bufferA,mapPtr,0,NULL,NULL);
把buffer object映射到主機地址空間。