获取向量中第一个“真”的索引
Posted
技术标签:
【中文标题】获取向量中第一个“真”的索引【英文标题】:Get index of first "true" in vector 【发布时间】:2013-12-22 13:23:07 【问题描述】:如何有效地计算 OpenCL 向量中第一个“真”值的索引:
float4 f = (float4)(1, 2, 3, 4);
int i = firstTrue(f > 2);
在示例中,我想获得i=2
,因为 3 是第一个大于 2 的值。
我查看了http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/ 中的所有函数,但一无所获。
这是一种不常见的操作吗? 如何在没有太多分支/代码重复的情况下(自行)计算?
【问题讨论】:
【参考方案1】:我不知道有一个内置函数可以完全满足您的需求,但我对如何做到这一点有一些想法。可能有一个更简单的解决方案,但到目前为止我只喝了一杯咖啡。这个想法是利用“计数前导零”功能“clz”。您只需要将条件结果转换为整数中的位位置。
-
创建一个布尔向量,通过比较设置真/假状态
将其与具有与位位置对应的预定义值的整数向量进行点积。
第一个位集将对应于您要求的索引。使用 clz() 或 bithack 来查找该位索引。
在代码中,类似这样的内容(未经测试,可能需要调整):
float4 f = (float4)(1, 2, 3, 4);
int4 greater = (f > 2);
int4 bits = (int4)(8, 4, 2, 1);
int sum = dot(greater, bits); // maybe this needs to use float
int index = clz(sum); // might need offset applied
您需要偏移或反转 clz 的结果以获得 0,1,2,3 但这只是加法或减法。
工作代码
int firstTrue(int4 v)
return 4 - (clz(0) - clz((v.x & 8) | (v.y & 4) | (v.z & 2) | (v.w & 1));
【讨论】:
嗯,编译器在点函数上给了我一个错误,并且只列出了floatn
和 doublen
的重载,似乎点函数不能应用于整数向量。
我在想可能是这样。在使用 clz 之前,您可以先转换为浮点数,然后再转换回整数。或者自己写点积(成员积的总和)。
非常聪明的解决问题的方法,节省了一些说明。
注意:For scalar types, the relational operators shall return 0 if the specified relation is false and 1 if the specified relation is true. For vector types, the relational operators shall return 0 if the specified relation is false and -1 (i.e. all bits set) if the specified relation is true.
(khronos.org/registry/cl/specs/opencl-1.2.pdf#page=218 d 部分结束)
我对此进行了更多思考,并意识到不需要点积。您可以在“int4 greater”上使用“clz”并将结果除以 sizeof(int) 以获得第一个真正元素的索引。以上是关于获取向量中第一个“真”的索引的主要内容,如果未能解决你的问题,请参考以下文章
matlab中怎么查找一个向量中第一个非零元素的位置 如P=[0;1;2] 第一个非零元素的位置为2,在mbtlab中怎么