2017-08-08 19 views
1

OpenCLテクノロジーでsha512を実装しています。私はカーネル関数の簡単な定義を持っていますOpenCLの文字をグローバルからローカルメモリ

__kernel void _sha512(__global char *message, const uint length, __global char *hash); 

私は実装して正常にsha512アルゴリズムの実装をテストしました。

message配列からcharacterという一時変数にデータをコピーする際に問題があります。範囲0からのメッセージのサイズに - iはループ変数である

char character = message[i]; 

。私はそこに私のプログラムを実行しようとしたとき

は、私はこのエラー

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()をreadedを得たが、私はそれを使用する方法を理解することはできません - ドキュメントでは、私はすべてのコード例を見つけることができません。

私はchar character = (__private char) message[i];で試しましたが、うまくいきません。

async_work_group_copy()に最後のパラメータを渡す方法と、__globalのメモリから__privateのメモリにデータをコピーする方法を理解できません。

答えて

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実装、およびハードウェアによって異なります。

もう1つのオプション(実装/ハードウェアが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にすることをお勧めします)

関連する問題