openCL

时间:2018-06-05 10:22:31

标签: c opencl

我有一个简单的任务,即根据以下规则扩展字符串FX

X -> X+YF+
Y-> -FX-Y

在OpenCL中,不支持字符串操作,但使用字符数组。并行扩展此字符串的内核程序如何在openCL中显示?

更多详情: 考虑一下' FX'在下面的python代码中。

axiom = "FX"
def expand(s):
    switch = {
        "X": "X+YF+",
        "Y": "-FX-Y",
    }
    return switch.get(s, s)


def expand_once(string):
    return [expand(c) for c in string]


def expand_n(s, n):
    for i in range(n):
        s = ''.join(expand_once(s))
    return s


expanded = expand_n(axiom, 200)

结果expanded将是扩展公理' FX' 200次。这是一个相当缓慢的过程,因此需要在openCL上进行并行化。 这个过程产生一个字符串数组,然后我将用它来绘制龙曲线。

下面是我如何想出这样一条龙曲线的例子:这部分并不重要。 OpenCL的扩展是至关重要的部分。

 import turtles
    from PIL import Image
turtles.setposition(5000, 5000)
turtles.left(90)  # Go up to start.


for c in expanded:
    if c == "F":
        turtles.forward(10)
    elif c == "-":
        turtles.left(90)
    elif c == "+":
        turtles.right(90)

# Write out the image.
im = Image.fromarray(turtles.canvas)
im.save("dragon_curve.jpg")

1 个答案:

答案 0 :(得分:1)

像这样的递归算法并不特别适合GPU加速,特别是当数据集在每次迭代时改变其大小时。

如果您确实需要迭代地执行此操作,那么挑战在于每个工作项都要知道输出字符串中放置结果的位置。一种方法是为工作组分配输入的特定子字符串,并在每次迭代时,保持输出的每个工作组大小的子字符串中的X和Y总数的计数。从中可以计算出子串在一次迭代中将展开多少,如果累积这些值,您将知道每个子串扩展的输出的偏移量。这是否有效是另一个问题。 : - )

但是,您的算法实际上是可预测的:您可以精确计算最终字符串的初始字符串和迭代次数的大小。使用OpenCL生成此字符串的最佳方法是提出一个非递归函数,该函数在给定M次迭代的情况下分析计算位置N处的字符,然后在每个工作项中调用该函数一次,使用(已知!)final字符串的长度作为工作大小。我不知道是否有可能提出这样的功能,但似乎可能是这样,如果有可能,这可能是在GPU上进行此操作的最有效方法。

似乎这可能是可能的:据我所知,结果将是高度周期性的:

FX
FX+YF+
FX+YF++-FX-YF+
FX+YF++-FX-YF++-FX+YF+--FX-YF+
FX+YF++-FX-YF++-FX+YF+--FX-YF++-FX+YF++-FX-YF+--FX+YF+--FX-YF+
^^^^^^ ^^^^^^^ ^^^^^^^ ^^^^^^^ ^^^^^^^ ^^^^^^^ ^^^^^^^ ^^^^^^^
  A*      B       A       B       A       B       A       B

据我所知,那些A块都是相同的,B也是如此。 (除了第一个有效位于-1的A之外)因此,您可以完全确定地确定每16个中的14个位置的字符。我强烈怀疑有可能计算出连接它们的+-的模式。如果你想出来,解决方案变得非常简单。

请注意,当你拥有该功能时,你可能甚至不需要将结果放在一个巨大的字符串中:你可以直接用该函数提供绘图算法。