【发布时间】:2015-10-08 08:35:24
【问题描述】:
我有一个庞大的数组需要搜索(实际上它是一个由较小数组组成的庞大数组,但出于所有意图和目的,让我们将其视为一个巨大的数组)。我需要找到的是一系列特定的数字。显然,一个简单的 for 循环就可以了:
Pseudocode:
for(x = 0; x++) {
if(array[x] == searchfor[location])
location++;
else
location = 0;
if(location >= strlen(searchfor))
return FOUND_IT;
}
问题是我希望它高效。在一个完美的世界里,我不想从 OpenCL 内核返回准备好的数据并做一个简单的搜索循环。
我对非 OpenCL 的想法持开放态度,但我可以在 1024 的目标数组长度上跨 64 个工作组大小实施的东西将是理想的。
我正在考虑想法(在工作项之间拆分目标,比较每个项目,循环,针对每个目标,如果匹配,设置一个标志。在所有工作项完成后,检查标志。虽然在我写的时候,这听起来效率很低)但我确定我错过了一些东西。
另一种想法是,由于目标数组是 uchar,因此将其合并为一个双精度数组,并一次检查 8 个索引。不确定我是否可以轻松地在 opencl 中做到这一点。
还玩弄了用一些快速的东西(可能是 MD5)对搜索目标进行哈希处理的想法,然后一次抓取 strlen(searchtarget) 个字符,对其进行哈希处理,然后查看它是否匹配。不确定哈希会在多大程度上影响我的搜索速度。
哦 - 代码是 C 语言,所以没有 C++ 映射(我在谷歌搜索时发现的东西似乎有帮助?)
【问题讨论】:
-
memmem() 怎么样 - 你允许 gnu 扩展吗?
-
散列不会帮助你。计算 n 项的哈希值比仅对每个项进行比较更昂贵。
-
通过将数据视为具有不同类型来复用数据会在 C99 中产生未定义的行为,这在 OpenCL 上下文中似乎是一个特别糟糕的问题,因为它专注于异构硬件。它还要求您通过未对齐的指针读取数据,这本身也会产生未定义的行为。
-
除非数据具有某种可以用来简化搜索的结构,否则除了直接搜索之外确实没有其他好方法。但是,您可以将工作数组拆分为多个块并并行搜索每个块。一定要重叠块的末端,这样你的目标就不会因为被分成两个块而逃避检测。这似乎比拆分目标要简单得多,而且它的优点是任何定位目标的任务都可以提前退出。
-
使用 memchr() 在数组中搜索与搜索字符串的第一个字符相等的位置,然后比较字符串。 memchr() 通常根据您使用的编译器进行优化。