我有一个程序必须处理大量数据并根据某种模式将其分组。我会谈一点。
该数据表示为矩阵,其中每列是不同的元素,其被分成“子元素”。程序采用这个“子元素”并遍历每个模式(模式由DFA表示 - 确定性有限自动机*)以查看元素属于哪个组(该元素不属于多个组)
下图以可视方式解释数据组织。
CPU-CODE - 首先我用CPU代码写了这个程序。它完全序列化。程序从元素中获取每个子元素,并检查元素是否属于一个元素 小组检查第一个模式。如果不这样做,请查看第二种模式。等等。当第一个元素被分类时,检查第二个元素,然后检查第三个元素,依此类推。 的 / CPU-CODE
如何看,如果并行化,这段代码可以快得多。然后该程序在CUDA中编码。
GPU-CODE - 要在低内存传输的GPU中运行代码,所有数据和自动机都会在“分类代码”启动之前传输到GPU内存。现在的区别是 我可以启动很多线程和块,每个线程将采用一个元素并对其进行分类。下图说明了如何在GPU中完成。
GPU代码比CPU代码快得多。的 / GPU-CODE
现在问题: 就像我说的那样,模式被检查进入自动机。自动机具有一些状态,每个状态都有一些转换。转换次数几乎不会大于6.由于内存限制,自动机不会在默认模式下表示,只需在表中查看一次即可获得下一个状态(表编码)。
我的编码需要多个外观才能获得下一个状态。为了获得下一个状态,我采用子元素并检查第一个转换是否由它触发。如果没有,我检查第二次转换,依此类推。
如果不够清楚,上面的CPU和GPU代码都会在自动机状态内以串行方式行走。换句话说,它会检查第一个转换,看看我们是否与下一个状态匹配。如果没有,请检查下一个转换,依此类推。
我想在每个州内并行化此搜索。换句话说,我想要每个过渡一个线程。就像我说的那样,状态中的转换数量几乎不会大于6.我知道似乎没有必要并行化它,因为转换次数很少,但这部分代码(匹配)会重复多次。 / p>
我尝试在每个状态下并行化此搜索,但执行时间比串行代码大。 我将在下面解释我是如何完成我的天真实施的:
对于这个测试,我使用的自动机每个状态最多有4个转换(但它可以少于4个)。所以我在线程块的Y维度中启动了4个线程(X维度线程采用元素,Y维度线程采用子元素)并在共享内存中创建一个数组,如果我有“转换匹配“或不。这个数组具有块的大小(blockDim.x * blockDim.Y),因为它是对所有元素完成的。
问题是:有时我每个状态的转换次数少于4次,这意味着线程3可以检查其他状态,而不是我感兴趣的状态并且匹配错误。这个问题迫使我进行“第一次匹配”搜索,我以串行的方式进行搜索,这与我之前做的相同,但现在我有一个与创建线程和数组相关的开销(我设置了数组数组的元素为0,开销更大。因此,我什么也没做。
为了清楚说明,这张图片展示了我试图做的事情。
我之前已经问过如何在stackoverflow中进行第一次匹配搜索,但我的问题是遗漏了一些关于我的代码和我的问题的重要细节,我在这里解释。
所以我的问题是,我可以有效地在每个状态内并行化这种搜索(即使只有少量的转换),或者它是不值得的,我应该使用我的序列化GPU代码?
如果你认为我可以并行化,我应该使用我的最后一个代码更好地实现“第一匹配”搜索,还是应该使用完全不同的方法?