我在OpenCL技术中实施sha512。我有简单的内核函数定义
__kernel void _sha512(__global char *message, const uint length, __global char *hash);
在主机上我已经实现并成功测试了sha512算法的实现。
我将message
数组中的数据复制到名为character
的临时变量时出现问题。
char character = message[i];
i
是一个循环变量 - 范围从0到消息的大小。
当我尝试在那里运行我的程序时,我遇到了这个错误
0x00007FFD9FA03D54 (0x0000000010CD0F88 0x0000000010CD0F88 0x0000000010BAEE88 0x000000001A2942A0), nvvmCompilerProperty() + 0x26174 bytes(s)
...
0x00007FFDDFA70D51 (0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000), RtlUserThreadStart() + 0x21 bytes(s)
0x00007FFDDFA70D51 (0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000), RtlUserThreadStart() + 0x21 bytes(s)
我对async_work_group_copy()感到厌烦,但我无法理解如何使用它 - 在文档中我无法找到任何示例代码。
我尝试使用char character = (__private char) message[i];
,但它也没有用。
我不明白如何将最后一个参数传递到async_work_group_copy()
以及如何使用它将数据从__global
内存复制到__private
内存。
答案 0 :(得分:1)
默认情况下,OpenCL不允许在内核中进行单字节访问:内存访问需要是4个字节的倍数,与4字节边界对齐。如果您的实现支持它,您可以启用逐字节内存访问。这涉及cl_khr_byte_addressable_store extension,您需要在内核源代码中检查并明确启用它。试一试,看看它是否解决了你的问题。
要使用async_work_group_copy
,请尝试以下操作:
#define LOCAL_MESSAGE_SIZE 64 // or some other suitable size for your workgroup
__local char local_message[LOCAL_MESSAGE_SIZE];
event_t local_message_ready = async_work_group_copy(local_message, message, LOCAL_MESSAGE_SIZE, 0);
// ...
// Just before you need to use local_message's content:
wait_group_events(1, &local_message_ready);
// Use local_message from here onwards
请注意,async_work_group_copy
不是必需的;您可以直接访问全局内存。哪个更快取决于您的内核,OpenCL实现和硬件。
另一个选项(如果您的实现/硬件不支持cl_khr_byte_addressable_store,唯一的选择)是以至少4个字节的块为单位获取数据。将您的message
声明为__global uint*
并通过移动和屏蔽来解压缩字节:
uint word = message[i];
char byte0 = (word & 0xff);
char byte1 = ((word >> 8) & 0xff);
char byte2 = ((word >> 16) & 0xff);
char byte3 = ((word >> 24) & 0xff);
// use byte0..byte3 in your algorithm
根据实现,硬件等,您可能会发现这比按字节访问更快。 (如果您不确定所有部署平台是否都是小端的话,您可能需要check if you need to reverse the unpacking by reading the CL_DEVICE_ENDIAN_LITTLE
property using clGetDeviceInfo
。)