您可以捐助,支持我们的公益事业。

1元 10元 50元





认证码:  验证码,看不清楚?请点击刷新验证码 必填



  求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Modeler   Code  
会员   
 
   
 
 
     
   
 订阅
  捐助
AMD OpenCL大学课程(3)
 
译者:迈克老狼2012,火龙果软件 发布于:2014-11-05
   次浏览      
 

OpenCL内存对象:

OpenCL内存对象就是一些OpenCL数据,这些数据一般在设备内存中,能够被拷入也能够被拷出。OpenCL内存对象包括buffer对象和image对象。

buffer对象:连续的内存块----顺序存储,能够通过指针、行列式等直接访问。

image对象:是2维或3维的内存对象,只能通过read_image() 或 write_image()来读取。image对象可以是可读或可写的,但不能同时既可读又可写。

该函数会在指定的context上创建一个buffer对象,image对象相对比较复杂,留在后面再讲。

flags参数指定buffer对象的读写属性,host_ptr可以是NULL,如果不为NULL,一般是一个有效的host buffer对象,这时,函数创建OpenCL buffer对象后,会把对应host buffer的内容拷贝到OpenCL buffer中。

在Kernel执行之前,host中原始输入数据必须显式的传到device中,Kernel执行完后,结果也要从device内存中传回到host内存中。我们主要通过函数clEnqueue{Read|Write}{Buffer|Image}来实现这两种操作。从host到device,我们用clEnqueueWrite,从device到host,我们用clEnqueueRead。clEnqueueWrite命令包括初始化内存对象以及把host 数据传到device内存这两种操作。当然,像前面一段说的那样,也可以把host buffer指针直接用在CreateBuffer函数中来实现隐式的数据写操作。

这个函数初始化OpenCL内存对象,并把相应的数据写到OpenCL内存关联的设备内存中。其中,blocking_write参数指定是数拷贝完成后函数才返回还是数据开始拷贝后就立即返回(阻塞模式于非阻塞模式)。Events参数指定这个函数执行之前,必须要完成的Event(比如先要创建OpenCL内存对象的Event)。

OpenCL程序对象:

程序对象就是通过读入Kernel函数源代码或二进制文件,然后在指定的设备上进行编译而产生的OpenCL对象。

这个函数通过源代码(strings),创建一个程序对象,其中counts指定源代码串的数量,lengths指定源代码串的长度(为NULL结束的串时,可以省略)。当然,我们还必须自己编写一个从文件中读取源代码串的函数。

对context中的每个设备,这个函数编译、连接源代码对象,产生device可以执行的文件,对GPU而言就是设备对应shader汇编。如果device_list参数被提供,则只对这些设备进行编译连接。options参数主要提供一些附加的编译选项,比如宏定义、优化开关标志等等。

如果程序编译失败,我们能够根据返回的状态,通过调用clGetProgramBuildInfo来得到错误信息。

加上创建内存对象以及程序对象的代码如下:

1: 
  2: #include "stdafx.h"
  3: #include 
  4: #include 
  5: #include 
  6: #include 
  7: #include 
  8: #include 
  9: 
  10: using namespace std;
  11: #define NWITEMS 262144
  12: 
  13: #pragma comment (lib,"OpenCL.lib")
  14: 
  15: //把文本文件读入一个string中
  16: int convertToString(const char *filename, std::string& s)
  17: {
  18: size_t size;
  19: char* str;
  20: 
  21: std::fstream f(filename, (std::fstream::in | std::fstream::binary));
  22: 
  23: if(f.is_open())
  24: {
  25: size_t fileSize;
  26: f.seekg(0, std::fstream::end);
  27: size = fileSize = (size_t)f.tellg();
  28: f.seekg(0, std::fstream::beg);
  29: 
  30: str = new char[size+1];
  31: if(!str)
  32: {
  33: f.close();
  34: return NULL;
  35: }
  36: 
  37: f.read(str, fileSize);
  38: f.close();
  39: str[size] = '\0';
  40: 
  41: s = str;
  42: delete[] str;
  43: return 0;
  44: }
  45: printf("Error: Failed to open file %s\n", filename);
  46: return 1;
  47: }
  48: 
  49: int main(int argc, char* argv[])
  50: {
  51: //在host内存中创建三个缓冲区
  52: float *buf1 = 0;
  53: float *buf2 = 0;
  54: float *buf = 0;
  55: 
  56: buf1 =(float *)malloc(NWITEMS * sizeof(float));
  57: buf2 =(float *)malloc(NWITEMS * sizeof(float));
  58: buf =(float *)malloc(NWITEMS * sizeof(float));
  59: 
  60: //初始化buf1和buf2的内容
  61: int i;
  62: srand( (unsigned)time( NULL ) );
  63: for(i = 0; i < NWITEMS; i++)
  64: buf1[i] = rand()%65535;
  65: 
  66: srand( (unsigned)time( NULL ) +1000);
  67: for(i = 0; i < NWITEMS; i++)
  68: buf2[i] = rand()%65535;
  69: 
  70: cl_uint status;
  71: cl_platform_id platform;
  72: 
  73: //创建平台对象
  74: status = clGetPlatformIDs( 1, &platform, NULL );
  75: 
  76: cl_device_id device;
  77: 
  78: //创建GPU设备
  79: clGetDeviceIDs( platform, CL_DEVICE_TYPE_GPU,
  80: 1,
  81: &device,
  82: NULL);
  83: //创建context
  84: cl_context context = clCreateContext( NULL,
  85: 1,
  86: &device,
  87: NULL, NULL, NULL);
  88: //创建命令队列
  89: cl_command_queue queue = clCreateCommandQueue( context,
  90: device,
  91: CL_QUEUE_PROFILING_ENABLE, NULL );
  92: //创建三个OpenCL内存对象,并把buf1的内容通过隐式拷贝的方式
  93: //拷贝到clbuf1,buf2的内容通过显示拷贝的方式拷贝到clbuf2
  94: cl_mem clbuf1 = clCreateBuffer(context,
  95: CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
  96: NWITEMS*sizeof(cl_float),buf1,
  97: NULL );
  98: 
  99: cl_mem clbuf2 = clCreateBuffer(context,
  100: CL_MEM_READ_ONLY ,
  101: NWITEMS*sizeof(cl_float),NULL,
  102: NULL );
  103: 
  104: status = clEnqueueWriteBuffer(queue, clbuf2, 1,
  105: 0, NWITEMS*sizeof(cl_float), buf2, 0, 0, 0);
  106: 
  107: cl_mem buffer = clCreateBuffer( context,
  108: CL_MEM_WRITE_ONLY,
  109: NWITEMS * sizeof(cl_float),
  110: NULL, NULL );
  111: 
  112: const char * filename = "add.cl";
  113: std::string sourceStr;
  114: status = convertToString(filename, sourceStr);
  115: const char * source = sourceStr.c_str();
  116: size_t sourceSize[] = { strlen(source) };
  117: 
  118: //创建程序对象
  119: cl_program program = clCreateProgramWithSource(
  120: context,
  121: 1,
  122: &source,
  123: sourceSize,
  124: NULL);
  125: //编译程序对象
  126: status = clBuildProgram( program, 1, &device, NULL, NULL, NULL );
  127: if(status != 0)
  128: {
  129: printf("clBuild failed:%d\n", status);
  130: char tbuf[0x10000];
  131: clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_LOG, 0x10000, tbuf, NULL);
  132: printf("\n%s\n", tbuf);
  133: return -1;
  134: }
  135: 
  136: 
  137: 
  138: if(buf)
  139: free(buf);
  140: if(buf1)
  141: free(buf1);
  142: if(buf2)
  143: free(buf2);
  144: 
  145: //删除OpenCL资源对象
  146: clReleaseMemObject(clbuf1);
  147: clReleaseMemObject(clbuf2);
  148: clReleaseMemObject(buffer);
  149: clReleaseProgram(program);
  150: clReleaseCommandQueue(queue);
  151: clReleaseContext(context);
  152: return 0;
  153: }
  154: 

   
次浏览       
相关文章

企业架构、TOGAF与ArchiMate概览
架构师之路-如何做好业务建模?
大型网站电商网站架构案例和技术架构的示例
完整的Archimate视点指南(包括示例)
相关文档

数据中台技术架构方法论与实践
适用ArchiMate、EA 和 iSpace进行企业架构建模
Zachman企业架构框架简介
企业架构让SOA落地
相关课程

云平台与微服务架构设计
中台战略、中台建设与数字商业
亿级用户高并发、高可用系统架构
高可用分布式架构设计与实践
最新活动计划
LLM大模型应用与项目构建 12-26[特惠]
QT应用开发 11-21[线上]
C++高级编程 11-27[北京]
业务建模&领域驱动设计 11-15[北京]
用户研究与用户建模 11-21[北京]
SysML和EA进行系统设计建模 11-28[北京]

专家视角看IT与架构
软件架构设计
面向服务体系架构和业务组件
人人网移动开发架构
架构腐化之谜
谈平台即服务PaaS


面向应用的架构设计实践
单元测试+重构+设计模式
软件架构师—高级实践
软件架构设计方法、案例与实践
嵌入式软件架构设计—高级实践
SOA体系结构实践


锐安科技 软件架构设计方法
成都 嵌入式软件架构设计
上海汽车 嵌入式软件架构设计
北京 软件架构设计
上海 软件架构设计案例与实践
北京 架构设计方法案例与实践
深圳 架构设计方法案例与实践
嵌入式软件架构设计—高级实践
更多...