我同意 cmets,前提是推力不提供以“典型推力方式”执行此操作的单一功能,并且您不想使用一系列推力功能(例如循环),因为那可能是效率很低。
可以编写一个相当简单的 CUDA 内核,以蛮力方式执行此操作。
对于相对简单的 CUDA 内核,我们可以通过简单地将 CUDA 内核代码作为函子传递给每个元素的推力操作,例如 thrust::transform 或thrust::for_each.
这是一个例子:
$ cat t462.cu
#include <iostream>
#include <thrust/device_vector.h>
#include <thrust/transform.h>
#include <thrust/copy.h>
#include <thrust/iterator/counting_iterator.h>
struct my_f
{
char *array, *string;
size_t arr_len;
int str_len;
my_f(char *_array, size_t _arr_len, char *_string, int _str_len) :
array(_array), arr_len(_arr_len), string(_string), str_len(_str_len) {};
__host__ __device__
bool operator()(size_t idx){
for (int i=0; i < str_len; i++)
if ((i+idx)>= arr_len) return false;
else if (array[i+idx] != string[i]) return false;
return true;
}
};
int main(){
char data[] = "aaaabaaab";
char str[] = "ab";
size_t data_len = sizeof(data)-1;
int str_len = sizeof(str)-1;
thrust::device_vector<char> d_data(data, data+data_len);
thrust::device_vector<char> d_str(str, str+str_len);
thrust::device_vector<bool> result(data_len);
thrust::transform(thrust::counting_iterator<size_t>(0), thrust::counting_iterator<size_t>(data_len), result.begin(), my_f(thrust::raw_pointer_cast(d_data.data()), data_len, thrust::raw_pointer_cast(d_str.data()), str_len));
thrust::copy(result.begin(), result.end(), std::ostream_iterator<bool>(std::cout, ","));
std::cout << std::endl;
}
$ nvcc -o t462 t462.cu
$ ./t462
0,0,0,1,0,0,0,1,0,
$
我不知道这种“蛮力”方法对于这类问题是否有效。可能有更好/更有效的方法,尤其是在搜索出现较长字符串时。