Vector OpenCL结果根据printf的结果而变化?什么

Vector OpenCL结果根据printf的结果而变化?什么,vector,opencl,Vector,Opencl,OpenCL内核处理一些数字。然后,这个特定的内核在8位char4向量的数组中搜索匹配的数字字符串。例如,数组包含36782561378202-内核在该数组上循环(实际字符串长度为1024位),搜索13782并“返回”数据,让主机程序知道它找到了匹配项 在一个组合学习练习/编程实验中,我想看看是否可以在一个数组上循环并搜索一系列值,其中数组不仅仅是char值,而是char4向量,而不需要在内核中使用单个if语句。原因有二: 1:在半个小时的编译错误之后,我意识到你不能: if(charvecto

OpenCL内核处理一些数字。然后,这个特定的内核在8位char4向量的数组中搜索匹配的数字字符串。例如,数组包含36782561378202-内核在该数组上循环(实际字符串长度为1024位),搜索13782并“返回”数据,让主机程序知道它找到了匹配项

在一个组合学习练习/编程实验中,我想看看是否可以在一个数组上循环并搜索一系列值,其中数组不仅仅是char值,而是char4向量,而不需要在内核中使用单个if语句。原因有二:

1:在半个小时的编译错误之后,我意识到你不能:

if(charvector[3] == searchvector[0])
因为有些可能匹配,有些可能不匹配。和2:

我是OpenCL新手,我读过很多关于分支如何影响内核速度的书,如果我正确理解内核的内部结构,一些数学运算可能实际上比if语句更快。是这样吗

无论如何。。。首先,所讨论的内核:

void search(__global uchar4 *rollsrc, __global uchar *srch, char srchlen)
{
  size_t gx = get_global_id(0);
  size_t wx = get_local_id(0);
  __private uint base = 0;
  __local uchar4 queue[8092];
  __private uint chunk = 8092 / get_local_size(0);
  __private uint ctr, start, overlap = srchlen-1;
  __private int4 srchpos = 0, srchtest = 0;
  uchar4 searchfor;
  event_t e;

  start = max((int)((get_group_id(0)*32768) - overlap), 0);

  barrier(CLK_LOCAL_MEM_FENCE);
  e = async_work_group_copy(queue, rollsrc+start, 8092, 0);
  wait_group_events(1, &e);

  for(ctr = 0; ctr < chunk+overlap; ctr++) {
    base = min((uint)((get_group_id(0) * chunk) + ctr), (uint)((N*32768)-1));
    searchfor.x = srch[max(srchpos.x, 0)]; 
    searchfor.y = srch[max(srchpos.y, 0)]; 
    searchfor.z = srch[max(srchpos.z, 0)]; 
    searchfor.w = srch[max(srchpos.w, 0)]; 
    srchpos += max((convert_int4(abs_diff(queue[base], searchfor))*-100), -100) | 1;
    srchpos = max(srchpos, 0);
    srchtest = clamp(srchpos-(srchlen-1), 0, 1) << 31;
    srch[0] |= (any(srchtest) * 255); 

//  if(get_group_id(0) == 0 && get_local_id(0) == 0) 
//    printf("%u: %v4u   %v4u\n", ctr, srchpos, srchtest);
  }
  barrier(CLK_LOCAL_MEM_FENCE);
}
其作用:获取目标队列(队列)中当前位置与前4行中设置的searchfor向量之间的ABS差值。返回一个向量,其中每个成员将有一个正数(不匹配)或零(匹配-无差异)

它被转换为int4(因为uchar不能为负),然后乘以-100,然后运行max(x,-100)。现在向量要么是-100,要么是0。我们用1或它,现在它是-99或1

最终结果:searchpos增加1(匹配),或减少99,重置以前的部分匹配增量。(搜索长度可达96个字符-有可能匹配91个字符,然后错过,因此它必须能够清除所有字符)。然后用0将其最大化,因此任何负结果都被钳制为零。再次-开放的建议,使之更有效。当我写这篇文章的时候,我意识到我可能会使用加法和饱和来删除一些max语句


最后一部分获取当前的srchpos,它现在等于连续匹配的数量,减去搜索字符串长度的1,然后将其钳制为0-1,从而得到1-a完全匹配或0。对于将来引用此问题的任何人,此问题是由我的数组被读取超出范围引起的。当这种情况发生时,一切都会失控,所有结果都是不可预测的


一旦我确定了工作和组大小,并确保没有超出内存限制,它就可以正常工作。

您能否提供完整的内核代码,并描述如何启动它(全局和局部大小、参数值)?这就是完整的内核代码。除非你是说其他不相关的内核?全局大小为32768,本地大小为64<代码>EC(“Ksearch”,clEnqueueNDRangeKernel(命令队列,内核搜索,1,NULL,&conv_大小,&conv_工作,0,NULL,&event))是发射线。conv_size和conv_work是32768和64的整数。内核的参数是缓冲区。EC是一个检查和停止/报告错误的宏。可以肯定的是,我刚刚添加了一个新的uint全局缓冲区,4字节,将其设置为0,将其作为全局uint*retval传递给内核,如果匹配,我将retval设置为255。如果没有printf,它将在内核完成后读取0。对于printf,它的读数为255。我想消除使用搜索词作为返回值的黑客行为。仍然不起作用。好吧,内核中使用的
N
宏/常量的值是多少?哇,你问这个问题让我完全明白了问题所在。这是处理此数据的系列中的第五个内核。所有其他内核都让每个工作项接受一个数字和工作的“线程”。这一个是最后一个,只是将整个结果数组作为一个长流读取,因此其工作方式不同。不幸的是,对于大小为32768*1024的数组,32768个工作项*8092(一个输入错误,应该是8192)远远超出了范围。因为我在复制以前的内核,它们都处理相同的数据,但不同,所以我没有想到工作大小/组对于输入数据来说太大。谢谢
max((convert_int4(abs_diff(queue[base], searchfor))*-100), -100) | 1;
36: 0,0,0,0   0,0,0,0
37: 0,0,0,0   0,0,0,0
38: 0,0,0,0   0,0,0,0
39: 0,0,0,0   0,0,0,0

Search = 613.384 ms
Positive
Done read loop: -1 27 41
Search = 0.150 ms
Negative
Done read loop: 55 27 41