【问题标题】:Efficient search for series of values in an array? Ideally OpenCL usable?有效搜索数组中的一系列值?理想情况下 OpenCL 是否可用?
【发布时间】: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() 通常根据您使用的编译器进行优化。

标签: c arrays search opencl


【解决方案1】:

基于上面的 cmets,对于未来的搜索,似乎一个简单的 for 循环扫描范围是在给定 OpenCL 实现的情况下查找匹配项的最有效方法。

【讨论】:

    【解决方案2】:

    创建一个索引数组[sizeof uchar]。对于搜索字符串中的每个 uchar,使 array[uchar] = uchar 首次出现的搜索字符串中的位置。数组的其余部分包含 -1。

    unsigned searchindexing[sizeof char] = { (unsigned)-1};
    memcpy(searchindexing + 1, searchindexing, sizeof char - 1);
    for (i = 0; i < strlen(searchfor); i++)
      searchindexing[searchfor[i]] = i;
    

    如果你不从头开始,一个 uchar 出现不止一次,就会在 searchindexing 中输入错误的位置。

    然后你通过步进 strlen(searchfor) 搜索数组,除非从 searchfor 中找到一个 uchar。

    for (i = 0; i < MAXARRAYLEN; i += strlen(searchfor))
      if ((unsigned)-1 != searchindexing[array[i]]) {
        i -= searchindexing[array[i]];
        if (!memcmp(searchfor, &array[i], strlen(searchfor)))
          return FOUND_IT;
      }
    

    如果数组中的大部分 uchar 不在搜索中,这可能是最快的方法。注意代码没有优化。

    示例:搜索 =“香蕉”。 strlen 为 6。 searchindexing['a'] = 5, ['b'] = 0, ['n'] = 4 其余的值不在 0 到 5 之间,例如 -1 或 maxuint。如果 array[i] 不是香蕉之类的空间,则 i 增加 6。如果 array[i] 现在是“a”,则您可能在香蕉中,它可以是 3 个“a”中的任何一个。所以我们假设最后一个'a'并向后移动5个位置并与searchfor进行比较。如果成功,我们就找到了,否则我们前进 6 步。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-02
      • 2011-09-08
      相关资源
      最近更新 更多