Asynchronous AMD clEnqueueMapBuffer和固定内存

Asynchronous AMD clEnqueueMapBuffer和固定内存,asynchronous,memory,opencl,gpu,Asynchronous,Memory,Opencl,Gpu,我目前使用的是AMD GPU /*device memory*/ pattern_obj = clCreateBuffer(context, CL_MEM_READ_ONLY, MAX_PATTERN_SIZE * MAX_PATTERN_NUM * sizeof(cl_char), NULL, &ret); text_objA = clCreateBuffer(context, CL_MEM_READ_ONLY, fileLen * sizeof(char) / 2, NULL, &a

我目前使用的是AMD GPU

/*device memory*/
pattern_obj = clCreateBuffer(context, CL_MEM_READ_ONLY, MAX_PATTERN_SIZE * MAX_PATTERN_NUM * sizeof(cl_char), NULL, &ret);
text_objA = clCreateBuffer(context, CL_MEM_READ_ONLY, fileLen * sizeof(char) / 2, NULL, &ret);
text_objB = clCreateBuffer(context, CL_MEM_READ_ONLY, fileLen * sizeof(char) / 2, NULL, &ret);
failure_obj = clCreateBuffer(context, CL_MEM_READ_ONLY, MAX_PATTERN_SIZE * MAX_PATTERN_NUM * sizeof(cl_int), NULL, &ret);
ret_objA = clCreateBuffer(context, CL_MEM_WRITE_ONLY, MAX_PATTERN_NUM * sizeof(cl_int), NULL, &ret);
ret_objB = clCreateBuffer(context, CL_MEM_WRITE_ONLY, MAX_PATTERN_NUM * sizeof(cl_int), NULL, &ret);

/*pinned memory*/
mPattern_obj = clCreateBuffer(context, CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR, MAX_PATTERN_SIZE * MAX_PATTERN_NUM * sizeof(cl_char), NULL, &ret);
mText_obj = clCreateBuffer(context, CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR, fileLen * sizeof(char), NULL, &ret);
mFailure_obj = clCreateBuffer(context, CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR, MAX_PATTERN_SIZE * MAX_PATTERN_NUM * sizeof(cl_int), NULL, &ret);
mRet_obj = clCreateBuffer(context, CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR, MAX_PATTERN_NUM * sizeof(cl_int) * 2, NULL, &ret);

/*mapped pointer for pinned memory*/
pattern = (cl_char *)clEnqueueMapBuffer(command_queue[0], mPattern_obj, CL_TRUE, CL_MAP_READ | CL_MAP_WRITE, 0, MAX_PATTERN_SIZE * MAX_PATTERN_NUM * sizeof(cl_char), 0, NULL, NULL, &ret);
strings = (char *)clEnqueueMapBuffer(command_queue[0], mText_obj, CL_TRUE, CL_MAP_READ | CL_MAP_WRITE, 0, fileLen * sizeof(char), 0, NULL, NULL, &ret);
failure = (cl_int *)clEnqueueMapBuffer(command_queue[0], mFailure_obj, CL_TRUE, CL_MAP_READ | CL_MAP_WRITE, 0, MAX_PATTERN_SIZE * MAX_PATTERN_NUM * sizeof(cl_int), 0, NULL, NULL, &ret);
matched = (cl_int *)clEnqueueMapBuffer(command_queue[0], mRet_obj, CL_TRUE, CL_MAP_READ | CL_MAP_WRITE, 0, MAX_PATTERN_NUM * sizeof(cl_int) * 2, 0, NULL, NULL, &ret);

/*Initialize the mapped pointer*/

ret = clEnqueueWriteBuffer(command_queue[0], pattern_obj, CL_FALSE, 0, MAX_PATTERN_SIZE * MAX_PATTERN_NUM * sizeof(cl_char), (void *)&pattern[0], 0, NULL, NULL);
ret = clEnqueueWriteBuffer(command_queue[0], text_objA, CL_FALSE, 0, halfSize, (void *)&strings[0], 0, NULL, NULL);
ret = clEnqueueWriteBuffer(command_queue[0], failure_obj, CL_FALSE, 0, MAX_PATTERN_SIZE * MAX_PATTERN_NUM * sizeof(cl_int), (void *)&failure[0], 0, NULL, NULL);

ret = clEnqueueNDRangeKernel(command_queue[0], kernel[0], 1, NULL, &global_item_size, &local_item_size, 0, NULL, &kmp_event); 

clWaitForEvents(1, &kmp_event);

ret = clEnqueueWriteBuffer(command_queue[1], pattern_obj, CL_FALSE, 0, MAX_PATTERN_SIZE * MAX_PATTERN_NUM * sizeof(cl_char), (void *)&pattern[0], 0, NULL, NULL);
ret = clEnqueueWriteBuffer(command_queue[1], text_objB, CL_FALSE, 0, halfSize, (void *)&strings[halfOffset], 0, NULL, NULL);
ret = clEnqueueWriteBuffer(command_queue[1], failure_obj, CL_FALSE, 0, MAX_PATTERN_SIZE * MAX_PATTERN_NUM * sizeof(cl_int), (void *)&failure[0], 0, NULL, NULL);

ret = clEnqueueNDRangeKernel(command_queue[1], kernel[1], 1, NULL, &global_item_size, &local_item_size, 0, NULL, &kmp_event);

clWaitForEvents(1, &kmp_event);

ret = clEnqueueReadBuffer(command_queue[0], ret_objA, CL_FALSE, 0, MAX_PATTERN_NUM * sizeof(cl_int), (void *)&matched[0], 0, NULL, NULL);

ret = clEnqueueReadBuffer(command_queue[1], ret_objB, CL_FALSE, 0, MAX_PATTERN_NUM * sizeof(cl_int), (void *)&matched[MAX_PATTERN_NUM], 0, NULL, NULL);
这是我的固定内存代码

我使用MapBuffer和固定内存进行重叠数据传输和执行

我知道我的代码是针对Nvidia GPU的,我认为Nvidia和AMD之间不匹配

AMD GPU没有关于重叠传输和计算的示例代码

所以,我不知道我要做什么

我应该改变什么使我的代码在AMD GPU中工作

我在A&B中划分了文本_obj,因为我想通过将文本分为正面和背面来传输文本


例如:text:“ababccc”text_objA=>abab和text_objB=>cccc

是的,NVIDIA和AMD的固定内存不同。NVIDIA有两个缓冲区(一个设备,一个主机)的奇怪要求,它神奇地检测到复制操作的主机指针是“特殊的”,这使得复制速度更快。请注意,在较新的驱动程序中,当映射/取消映射设备缓冲区时,可能会获得类似的性能。AMD也是这样做的(不需要两个缓冲区)。阅读AMD的开发者指南;他们有一整节是关于内存传输的。一句话:使用文档作为指导,但尝试所有方法并分析您的设备,以找到真正有效的方法。

谢谢!你的意思是,如果我尝试一些选项,是否有可能在AMD中重叠传输和执行?我看到一些评论提到AMD不支持它。我认为一些AMD板支持同时计算和传输;也许是壁炉。请注意,一些NVIDIA板具有双DMA引擎,您可以同时上载、计算和下载。您需要三个命令队列才能完成此任务。还有更多问题。1) 我对“下载”感到困惑。它的意思是“clenqueueredbuffer()”吗?2) 我参考了AMD优化指南并尝试了一些选项,但仍然不起作用。我使用一个缓冲区和两个命令队列对吗?3) 创建它们之后,我会执行两次setArg、writeBuffer和NDRangeKernel,以及两次readBuffer。怎么了?4) 另外,在每次使用writeBuffer和readBuffer之后,我都会放入clenqueunmapmemObject()。是吗?有很多问题需要评论。是的,“下载”是指阅读。您需要一个命令队列,以使每件事情重叠,而且非常重要的是,使用事件进行同步。我强烈建议首先使用一个命令队列来完成所有工作;多队列是专家级的东西。clEnqueueUnmapMemObject与writeBuffer/readBuffer无关,除非您谈论的是NVIDIA固定内存,然后您可以等到使用完它后再取消映射。