制作多处理器字符串评估算法

Making a multi-processor string evaluation algorithm

我有一个 Python 算法,它将两个字符串作为输入并对每个字符进行各种测试以获得 return 分数。 这通常涉及100对字符串,并且由于它不涉及写入内存,因此并发问题应该不是问题。

事情是,根据我的(小)GPU 编程经验,我记得在为 GPU(OpenGL 着色器)编码时需要制作简单的循环并为每个数组提供固定长度,这很烦人,因为字符串实际上是数组可变数组长度。

我可以考虑将 Python 字符串转换成 C-like char 数组,但这似乎是一个乏味的解决方案,并且没有解决制作简单循环的问题。

我的问题是这样的;有什么方法可以通过将这样的 Python 代码并行化到 GPU 来实现巨大的性能提升?有可能吗?

def evaluator( baseStr, listOfStr ) :
    for word in listOfStr : # PARALLELIZE THIS
        scoreList += [ evaluateTwoWords(baseStr, word) ];

def evaluateTwoWords(baseStr, otherStr) :

    SOME WORD-WISE COMPARISON

    i = 0; j = 0;

    while i < len(baseStr) and j < len(word) :
         ...

    return someScore;

对于上面提供的代码,是的,如果为 GPU 上的每个 thread/worker 分配一个任务来进行字符串比较,您可以在 GPU 上实现显着的加速。

但是 GPU 有一些限制。

1) If the string list to be loaded into the device memory is too huge,then  
   lost of system bandwidth is utilized to copy the string list from the 
   host to device memory. This context switch is one of the biggest setbacks 
   of using a GPU

2) Also a GPU becomes very effective in solving algorithms that have a lot 
   of SIMD(Single Instruction Multiple Data) characteristics. Check  
   this out for more info on SIMD https://en.wikipedia.org/wiki/SIMD. So the 
   more you start deviating from  SIMD,  the more penaltiy on speedup

下面是您程序的示例 Pycuda 版本

我使用过 PyCuda,但还有其他 OpencL python 驱动程序可以完成这项工作,因为 well.I 由于硬件限制,尚未测试下面的 GPU 代码,但我已经对其进行了编码主要来自这些示例 http://wiki.tiker.net/PyCuda/Examples

这就是代码的作用。

1) 复制字符串列表到gpu设备内存

2) 复制基础字符串到设备内存

3) 然后调用核函数return something

4) 最后使用求和或所需的减少减少 returned 值 您选择的功能

下面的代码是 SIMD 的一个完美示例,其中一个线程的结果独立于另一个线程的结果。但这只是一个理想的情况。您可能必须决定算法是否适合 GPU。

import pycuda.driver as cuda
import pycuda.autoinit
from pycuda.compiler import SourceModule

import numpy


string_list = ['Apple','Microsoft', 'Google','Facebook', 'Twitter']
string_list_lines = numpy.array( string_list, dtype=str)

#Allocalte mem  to list of strings on the GPU device
string_list_linesGPU = cuda.mem_alloc(string_list_lines.size * string_list_lines.dtype.itemsize)
#After allocation of mem,  copy it to gpu device memory
cuda.memcpy_htod(string_list_linesGPU, string_list_lines)

## ****** Now GPU device has list of strings loaded into it
## Same process applied for the base string too

baseStr = "Seagate"
baseStrGPU = cuda.mem_alloc( len(baseStr))
cuda.memcpy_htod(baseStrGPU, baseStr)

#Num of blocks
blocks = len(string_list)

#Threads per block
threadsPerBlock = 1


#Write the actual kernel function

mod = SourceModule("""
__global__ int evaluateTwoWords(char *string1, char **string2)
{
    idx = threadIdx.x;

    while len(string1) > len(string2){
        string2[i][0] = string1[0]s
        // you could probably foloow up with some kind of algorithm here 
    } 
    return len(string2)
}
""")

#Run the source model
gpusin = mod.get_function("evaluateTwoWords")
result  = 0
result += gpusin(destGPU, linesGPU, grid=(blocks,1), block=(threadsPerBlock,1,1))

return result

希望对您有所帮助!