我有一个长度最多为500个字符的字符串和一个大小为200MB的文本文件。我想在CUDA中编写一个程序来搜索文本文件中的字符串。我的文本文件太大了,我想我必须把它放在设备的全局内存中,但是我的字符串呢?哪个是共享,常量和纹理内存中最好的?为什么? 另外我有一个最大2500的数组。哪种类型的设备内存适合存储?
答案 0 :(得分:1)
对于费米的天真实施:
将文本文件存储在全局内存中,将搜索字符串存储在常量内存中。设置与文本文件大小相同的结果缓冲区。用零填充结果缓冲区。
让每个块的线程数 t 与搜索字符串的长度相同。要确定网格尺寸,请考虑文本文件的大小和网格尺寸限制为64K。要覆盖整个文件,请选择 x 的维度,例如10K。然后通过将文本文件的大小除以 x 并将结果四舍五入来找到 y 的维度。所以200M / 10K = 20K(在64K以内)。使用 t 线程和( x , y )网格启动内核。
在内核中:
计算文本文件的偏移量为 d = x + 1024 * y 。
由于 y 维度已向上舍入,因此必须中止运行结束时的某些内核。如果 d + t 高于文本文件的大小,则中止该线程。
否则,让线程从搜索字符串中加载索引 t 中的一个字符,并将其与索引 t + d 中的一个字符进行比较在文本文件中。如果字符不匹配,则在索引 d 的结果缓冲区中存储“1”,否则不执行任何操作。
内核完成后,使用Thrust扫描结果缓冲区。每个0的位置都标志着匹配的起点。
答案 1 :(得分:0)
假设您编写内核以使半warp中的所有线程同时访问搜索字符串的相同元素,则常量内存可能会产生良好的结果。它针对这种情况进行了优化。
这是一个简单基线实现的伪代码
...load blocksize+strlen bytes of the file into shared memory...
__syncthreads();
bool found = true;
for (int i = 0; i < strlen; i++) {
if (file_chunk_in_sharedmem[threadIdx.x + i] !=
search_str_in_constantmem[i])
{
found = false;
break;
}
}
if (found) {
...output the result...
}
如果循环的结构使得每个线程都访问搜索字符串的不同元素,那么1d纹理内存可能会更快。
探查器和/或cuda计时功能是你的朋友。