下面我发布了一些代码,试图了解CUDA推力库。在有人说什么之前,我知道这是一种效率极低的素数查找方法,我只想测试一下并行性。不幸的是,当我运行此程序时,我会出现一个错误:Unhandled exception at at 0x76FCC41F in Thrust_2.exe: Microsoft C++ exception: thrust::system::system_error at memory location 0x0022F500.
如果我在doTest函数中将device_vector
切换为host_vector
,我将不再收到错误,程序将完美运行。为什么会发生这种情况?我如何让它在不崩溃的情况下使用device_vector?我想尽可能多地同时做。此外,整个程序与host_vector一起正常工作。
PS:
我正在使用VS2012
Cuda:5.5
GPU:geforce gt 540M
推力:用木棒。
提前感谢!
struct prime{
__host__ __device__
void operator()(long& x){
bool result = true;
long stop = ceil(sqrt((float)x));
if(x%2!=0){
for(int i = 3;i<stop;i+=2){
if(x%i==0){
result = false;
break;
};
}
}else{
result = false;
}
if(!result)
x = -1;
}
};
void doTest(long gen){
using namespace thrust;
device_vector<long> tNum(gen);
sequence(tNum.begin(),tNum.end()); // fails here when using a device_vector
}
int main(){
doTest(1000);
return 0;
}
这是一个问题:
void operator()(long& x){
bool result = true;
long stop = ceil(sqrt(x));
事实上,你应该收到来自编译器的警告信息
设备代码中可用的sqrt
函数仅适用于float
和double
参数。您的参数类型为long
。这意味着编译器将尝试使用sqrt
函数的主机库版本,该版本在设备代码中不起作用。当您将向量创建为宿主向量时,这不是问题,因为函子是在宿主代码中运行的。然而,当您切换到设备向量时,函子(在设备上运行)将在该点崩溃,并引发推力错误。
作为一个简单的测试,您可以将其修改为:
long stop = ceil(sqrt((float)x));
看看它是否消除了崩溃。从long
到float
的转换是否对您的代码有效是您必须决定的。
问题是我有错误的编译器参数,我现在觉得真的很愚蠢。。。
我是为1.0编译的,我把它切换到2.0,现在它可以工作了。