“如何运行”;主持人;使用CUDA的GPU上的功能?

“如何运行”;主持人;使用CUDA的GPU上的功能?,cuda,Cuda,例如,我将在GPU上运行strcmp函数,但我得到: error: calling a host function("strcmp") from a __device__/__global__ function("myKernel") is not allowed 有可能是因为gpu没有标准输出,printf无法工作,但是像strcmp这样的函数应该可以工作!因此,我应该在我的代码中插入库中带有\uuu设备\uuu前缀的strcmp的实现,或者什么?CUDA有一个标准库,记录在CUDA编程指南

例如,我将在GPU上运行
strcmp
函数,但我得到:

error: calling a host function("strcmp") from a __device__/__global__ function("myKernel") is not allowed

有可能是因为gpu没有标准输出,
printf
无法工作,但是像strcmp这样的函数应该可以工作!因此,我应该在我的代码中插入库中带有
\uuu设备\uuu
前缀的
strcmp的实现,或者什么?

CUDA有一个标准库,记录在CUDA编程指南中。它包括用于支持它的设备(计算能力2.0及更高版本)的printf()以及assert()。但是,在这一点上,它不包括完整的字符串或stdio库

按照Jason R.Mick的建议实现您自己的标准库可能是可能的,但不一定是可取的。在某些情况下,将函数从顺序标准库简单地移植到CUDA可能是不安全的——尤其是因为其中一些实现并不意味着线程安全(例如,Windows上的rand()。即使它是安全的,它也可能没有效率——而且它可能不是你真正需要的

在我看来,您最好避免使用CUDA中未得到官方支持的标准库函数。如果需要并行代码中的标准库函数的行为,首先考虑是否真的需要它: *你真的要同时进行数千次strcmp行动吗? *如果没有,是否有数千个字符长的字符串进行比较?如果是,考虑一个并行字符串比较算法。

如果您确定您确实需要并行CUDA代码中的标准库函数的行为,那么考虑如何并行地实现它(安全和有效)。

< P>希望这将有助于至少一个人:

由于strcmp功能在CUDA中不可用,因此我们必须自行实现:

__device__ int my_strcmp (const char * s1, const char * s2) {
    for(; *s1 == *s2; ++s1, ++s2)
        if(*s1 == 0)
            return 0;
    return *(unsigned char *)s1 < *(unsigned char *)s2 ? -1 : 1;
}
\uuuuuu设备\uuuuuuu我的strcmp(常量字符*s1,常量字符*s2){
对于(;*s1==*s2;++s1,++s2)
如果(*s1==0)
返回0;
返回*(无符号字符*)s1<*(无符号字符*)s2?-1:1;
}

看看是什么让你认为“strcmp这样的功能应该可以工作”?CUDA标准库在CUDA编程指南附录中有明确说明。我在C标准库
string.h
中没有看到strcmp或其他任何内容。是吗?没错,Talonmes,但最好向他解释一下他如何添加这个功能…@Talonmes。。。。看看下面一个可能的平行模拟的起点。看看我更新的答案。。。我只是把他指向一块垫脚石。显然,你必须提防类型。在这种情况下,由于类型不同,抓取的函数似乎是安全的。然而,它并不理想,因为它没有利用固有的并行性。在最坏的情况下(与许多其他函数一样),它甚至可能不是线程安全的,正如您所指出的。无论如何,下一步显然是将函数并行化。在本例中,这应该不难——我在上面概述了一个半优化的建议。您的实现(3)是线程安全的。但是一些依赖静态数据的函数,如
rand()
,则不是。我的答案是更高层次的:OP假设标准库函数“预期能够工作”。我想解释为什么它们可能不会,为什么它们应该小心搬运。建议strcmp的优化并行实现是很好的,但它回避了我在回答中提出的问题:“您真的需要一个并行strcmp吗?”?您的第二个代码只有在所有线程都在同一个比较上进行协作时才有效(这对于短字符串来说可能是多余的)。诚然,原始代码是线程安全的,因为它不会修改其输入中的任何内容。在非常短的线程情况下,并行性可能过于致命,这建议使用混合方法--
if(size)