有关排列/散列的OpenCL和GPU需要注意的事项吗?

时间:2013-10-26 03:29:36

标签: opencl

我是OpenCL的新手,试图找出OpenCL和哈希的利弊。

比方说,我有一个简单的哈希函数:

public static uint GetHash(string str)
{
  uint s = 21; // seed
  foreach (char ch in str)
      s = (s + (uint)ch) * 10;
  return s;
}

(我知道这是一个可怕的哈希,但它只是一个例子)

现在假设我想计算字符a-zA-Z0-9_的所有排列长度为50,例如:

a
b
...
_
aa
ab
...
__

显然这是我需要计算的大量(63 ^ 50)哈希值,所以我决定使用OpenCL和GPU计算。

我的问题是:OpenCL / GPU计算带来了哪些陷阱?我读过以下内容:

  1. 通过PCIe总线传输数据是sloooooooowwwwwwwwwwwww
  2. 在GPU上访问全局内存是sloooooooooooowwwww
  3. warp中的所有“线程”必须执行相同的指令
  4. 这让我质疑GPU计算在这种情况下的有效性,因为在我看来,我需要使用以下方法之一:

    • 让每个线程计算自己的排列(违反#3,因为每个线程都有不同的增量数量)
    • 让每个线程预先形成一个影响所有其他线程的增量(违反#2)
    • 计算CPU上的排列并将它们发送到GPU(违反#1,加上我基本上只是使用GPU来计算哈希...)

    这些结论是否准确?如果没有,为什么,还有什么需要注意的吗?

1 个答案:

答案 0 :(得分:1)

慢是一个相对的术语。但一般来说,你想避免向GPU传输大量数据,或者换一种方式,你必须通过在GPU上进行大量计算来使数据传输的成本“值得”你将结果转回。

所以,按照你当前的说法(按照我的理解)查看你的问题,你想:

  1. 在主机(CPU)上生成每个可能的字符串
  2. 将原始字符串传输到GPU
  3. 在GPU上并行计算这些字符串的哈希值
  4. 将计算的哈希值传回主机(CPU)
  5. 这将运行得很糟糕,因为哈希的计算在计算上相当微不足道,并且大部分时间都花在执行数据传输上。

    绝对你想在GPU上生成字符串排列 - 这将避免(2)的成本。将这些拆分成工作项目应该不会太难。如果你有一个基本字符串,例如'aaaa',并且说,每个后缀字符有4个维度,然后计算每个线程中的哈希值(根据哈希函数,如果前缀'aaaa'的哈希值可以预先计算一次,你也可以节省大量资金。重复使用)并将其放在输出中。

    但我怀疑这种方法仍然会将生成的哈希值转移回主机。如果之后需要对哈希进行某些操作,例如检查与已知哈希的相等性,您也可以在GPU上执行此操作,避免所有这些代价高昂的数据传输,因为您需要回写的只是单个匹配(或可能是几个匹配)字符串/结果哈希到全局内存而不是63 ^ 50。