OpenCL强力TEA块32位,键64位

OpenCL强力TEA块32位,键64位,opencl,Opencl,我决定自己研究OpenCL并为TEA算法编写一个蛮力密码,我是否正确理解OpenCL?你能在速度方面有所改进吗?我犯了什么错误 我在循环中准备前5个字节,其余3个字节按内核排序,255个线程,每个线程65535个 在主程序中: for (int x5 = KEY[0]; x5 >= 0; x5--) { KEY[0]=x5; for (int x4 = KEY[1]; x4 >= 0; x4--) { KEY[1]=x4; for (int x3 = KEY[2]; x3 >=

我决定自己研究OpenCL并为TEA算法编写一个蛮力密码,我是否正确理解OpenCL?你能在速度方面有所改进吗?我犯了什么错误

我在循环中准备前5个字节,其余3个字节按内核排序,255个线程,每个线程65535个

在主程序中:

for (int x5 = KEY[0]; x5 >= 0; x5--) {
KEY[0]=x5;
for (int x4 = KEY[1]; x4 >= 0; x4--) {
KEY[1]=x4;
for (int x3 = KEY[2]; x3 >= 0; x3--) {
KEY[2]=x3;
for (int x2 = KEY[3]; x2 >= 0; x2--) {
KEY[3]=x2;
for (int x = KEY[4]; x >= 0; x--) {
KEY[4]=x;

ret = clEnqueueWriteBuffer(command_queue, key_mem_obj, CL_TRUE, 0,
8 * sizeof(int), KEY, 0, NULL, NULL);
ret = clEnqueueWriteBuffer(command_queue, cadr_mem_obj, CL_TRUE, 0,
1 * sizeof(int), CADR, 0, NULL, NULL);

ret = clSetKernelArg(kernel, 0, sizeof(cl_mem), (void *)&key_mem_obj);
ret = clSetKernelArg(kernel, 2, sizeof(cl_mem), (void *)&cadr_mem_obj);

NDRange = 0x0100;

ret = clEnqueueNDRangeKernel(command_queue, kernel, 1, NULL,
&NDRange, NULL, 0, NULL, NULL);
if (ret != CL_SUCCESS) {

break;
}

ret = clEnqueueReadBuffer(command_queue, cadr_mem_obj, CL_TRUE, 0,
1 * sizeof(int), CADR, 0, NULL, NULL);

if (CADR[0]>0) {

uint16_t k=CADR[0];

ret = clEnqueueReadBuffer(command_queue, retc_mem_obj, CL_TRUE, 0,
524280 * sizeof(int), RETC, 0, NULL, NULL);


for ((i = 0); i < k; i++) {
Form1->Memo1->Lines->BeginUpdate();
Form1->Memo1->Lines->Add(IntToHex(RETC[i*8],2)+IntToHex(RETC[i*8+1],2)+
IntToHex(RETC[i*8+2],2)+IntToHex(RETC[i*8+3],2)+IntToHex(RETC[i*8+4],2)+
IntToHex(RETC[i*8+5],2)+IntToHex(RETC[i*8+6],2)+IntToHex(RETC[i*8+7],2));
Form1->Memo1->Lines->EndUpdate();
    Form1->Label6->Caption=IntToStr(Form1->Memo1->Lines->Count-1);
}
CADR[0]=0;
}

KEY2[0]=KEY[0];
KEY2[1]=KEY[1];
KEY2[2]=KEY[2];
KEY2[3]=KEY[3];
KEY2[4]=KEY[4];
KEY2[5]=KEY[5];
KEY2[6]=KEY[6];
KEY2[7]=KEY[7];

if(Terminated){
break;
}
}
KEY[4]=0xFF;
}
KEY[3]=0xFF;
}
KEY[2]=0xFF;
}
KEY[1]=0xFF;
}
KEY[0]=0xFF;`
for(int x5=KEY[0];x5>=0;x5--){
键[0]=x5;
对于(int x4=键[1];x4>=0;x4--){
键[1]=x4;
对于(int x3=键[2];x3>=0;x3--){
键[2]=x3;
对于(int x2=键[3];x2>=0;x2--){
键[3]=x2;
对于(int x=键[4];x>=0;x--){
键[4]=x;
ret=clEnqueueWriteBuffer(命令队列,键mem,CL,TRUE,0,
8*sizeof(int),KEY,0,NULL,NULL);
ret=clEnqueueWriteBuffer(命令队列,cadr\U mem\U obj,CL\U TRUE,0,
1*sizeof(int),CADR,0,NULL,NULL);
ret=clSetKernelArg(kernel,0,sizeof(cl_mem),(void*)和key_mem_obj);
ret=clSetKernelArg(kernel,2,sizeof(cl_mem),(void*)和cadr_mem_obj);
NDRange=0x0100;
ret=clEnqueueNDRangeKernel(命令队列,内核,1,NULL,
&NDRange,NULL,0,NULL,NULL);
if(ret!=CL_SUCCESS){
打破
}
ret=CLENQUEUREADBUFFER(命令队列,cadr\U mem\U obj,CL\U TRUE,0,
1*sizeof(int),CADR,0,NULL,NULL);
如果(CADR[0]>0){
uint16_t k=CADR[0];
ret=clenqueueredbuffer(命令队列,retc\u mem\u obj,CL\u TRUE,0,
524280*sizeof(int),RETC,0,NULL,NULL);
对于((i=0);iMemo1->Lines->BeginUpdate();
表格1->备忘录1->行->添加(IntToHex(RETC[i*8],2)+IntToHex(RETC[i*8+1],2)+
IntToHex(RETC[i*8+2],2)+IntToHex(RETC[i*8+3],2)+IntToHex(RETC[i*8+4],2)+
IntToHex(RETC[i*8+5],2)+IntToHex(RETC[i*8+6],2)+IntToHex(RETC[i*8+7],2));
Form1->Memo1->Lines->EndUpdate();
Form1->Label6->Caption=IntToStr(Form1->Memo1->Lines->Count-1);
}
CADR[0]=0;
}
键2[0]=键[0];
键2[1]=键[1];
键2[2]=键[2];
键2[3]=键[3];
键2[4]=键[4];
键2[5]=键[5];
键2[6]=键[6];
键2[7]=键[7];
如果(终止){
打破
}
}
键[4]=0xFF;
}
键[3]=0xFF;
}
键[2]=0xFF;
}
键[1]=0xFF;
}
键[0]=0xFF`
内核:

#pragma OPENCL EXTENSION cl_khr_byte_addressable_store : enable
#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable
#pragma OPENCL EXTENSION cl_khr_local_int32_base_atomics : enable
#pragma OPENCL EXTENSION cl_khr_global_int32_extended_atomics : enable
#pragma OPENCL EXTENSION cl_khr_local_int32_extended_atomics : enable

__kernel void    brute(__global const int *KEY, __global const int *DAT, __global int 
*CADR,__global int *RETC)
{

int i = get_global_id(0);

ushort Data[2];
ushort Key[4];

Key[0]=(KEY[0]<<8)+KEY[1];
Key[1]=(KEY[2]<<8)+KEY[3];
// Key[2]=(KEY[4]<<8)+KEY[5];
Key[3]=(KEY[6]<<8)+KEY[7];

Key[2] = (KEY[4]<<8) + i;

for (int j=0xFFFF; j>=0; j--){

Key[3]=j;

Data[0]=(DAT[0]<<8)+DAT[1];
Data[1]=(DAT[2]<<8)+DAT[3];

 ushort delta = 0x9e37;
ushort sum = (delta<<5);

for (uint n = 0;n < 32; ++n){
Data[1]-=(((Data[0])+Key[2])^(Data[0]+sum)^((Data[0]>>5)+Key[3]));
Data[0]-=(((Data[1]<<4)+Key[0])^(Data[1]+sum)^(Data[1]+Key[1]));
sum -= delta;
}

if ((Data[0]==0x0000) && (Data[1]==0x0000)){
int a=CADR[0];
atomic_inc(CADR);
RETC[a*8]=(Key[0] >> 8);
RETC[a*8+1]=(Key[0] & 0xFF);
RETC[a*8+2]=(Key[1] >> 8);
RETC[a*8+3]=(Key[1] & 0xFF);
RETC[a*8+4]=(Key[2] >> 8);
RETC[a*8+5]=(Key[2] & 0xFF);
RETC[a*8+6]=(Key[3] >> 8);
RETC[a*8+7]=(Key[3] & 0xFF);

}


}


}
#pragma OPENCL扩展cl_khr_字节可寻址存储:启用
#pragma OPENCL扩展cl_khr_global_int32_base_atomics:启用
#pragma OPENCL扩展cl_khr_local_int32_base_atomics:启用
#pragma OPENCL扩展cl_khr_global_int32_extended_atomics:启用
#pragma OPENCL扩展cl_khr_local_int32_extended_atomics:启用
__内核无效暴力(uuu全局常量int*KEY,uuu全局常量int*DAT,uu全局int
*CADR,uuu全局整数*RETC)
{
int i=获取全局id(0);
ushort数据[2];
ushort键[4];

键[0]=(键[0]如果您只启动256个线程,每个线程对同一事物进行65536次迭代,您的GPU将不会饱和,性能将非常差。GPU有数千个“核心”,如果您启动256个线程,您将只使用其中的256个线程,而其余线程保持空闲


GPU并行化的思想是将工作分解为尽可能多的不相关问题。在您的情况下,这意味着:启动256*65536个线程,每个线程执行一次迭代。这样性能会更好。

这也很大程度上取决于您的硬件;这是关于您的特定实现的问题吗(我们无法在您的硬件上测试)关于制作一个通用实现(任何硬件上的高效客户端)?我只是想澄清一下线程,因为我知道有256512个(每个视频卡都有自己的),我选择了编写代码256的最佳选项,这是键[5]256个线程同时启动并在键[6]上迭代密钥[7]=65536个使用常规循环的密钥(很抱歉,如果某些内容写得不正确,我使用google translator)我理解正确如果我这样做了,我会从视频卡中挤出最大值吗?
size\t work\u group\size;clGetKernelWorkGroupInfo(内核,设备id,CL\u内核工作组\u size,sizeof(size\t),&work\u group\u size,NULL);NDRange=0x010000;ret=clEnqueueNDRangeKernel(命令队列,内核,1,NULL,&NDRange,&work\u组大小,0,NULL,NULL);
启动内核时我不也这样做吗:
clEnqueueNDRangeKernel(命令队列,内核,1,NULL,65536,256,0,NULL);
???