-1

感谢@Eric Shiyin Kang 回复我的问题,但不是前缀“主机”或“设备”导致我的问题,经过一些尝试和错误,我发现错误是“成员数据始终为常数”举个例子:

struct OP {
    int N;
    __host__ __device__
    OP(const int n): N(n){};

    __host__ __device__
    UI operator()(const UI a) {
        int b = a * N;
        N++;
        return b;
    }
}
thrust::transform(A.begin(), A.end(), B.begin(), OP(2) );

在这种情况下,如果 A 是 {0, 1, 2, 3, ... },那么 B 是 {0, 2, 4, 6, 8},但实际的 B 应该是 {0, 3(1*( 2+1)), 8(2*(3+1)), 15(3*(4+1)),....}

我不知道是什么原因导致这种情况,推力设计的原因?谁能告诉我?

4

1 回答 1

1

对于您更新的 Q,主机 varN无法在设备代码中更新。在并行算法中多次更新共享变量通常是不安全的。

事实上,初始化开发向量的最快方法应该是在对象构建阶段使用花哨的迭代器,例如,

// v[]={0,2,4,6,8...}
thrust::device_vector<float> v(
        thrust::make_transform_iterator(
                thrust::counting_iterator<float>(0.0),
                _1 * 2.0),
        thrust::make_transform_iterator(
                thrust::counting_iterator<float>(0.0),
                _1 * 2.0) + SIZE);

// u[]={0,3,8,15...}
thrust::device_vector<float> u(
        thrust::make_transform_iterator(
                thrust::counting_iterator<float>(0.0),
                _1 * (_1 + 2.0)),
        thrust::make_transform_iterator(
                thrust::counting_iterator<float>(0.0),
                _1 * (_1 + 2.0)) + SIZE);

它会比定义序列和转换方式快几倍,因为后一种方法v不止一次地读取/写入整个设备内存。

请注意,上面的代码仅适用于 Thrust 1.6.0+,因为 lambda 表达式仿函数与花哨的迭代器一起使用。对于 CUDA 5.0 中的 Thrust 1.5.3,您应该显式地编写一个仿函数。


A 为已被删除的原始 Q。

您可以在like前面添加__host__和限定词,__device__operator()()

struct OP {
    __host__ __device__ void operator()(int &a) {
        a *=2;
    }
}

struct OP {
    __host__ __device__ int operator()(int a) {
        return a*2;
    }
}

否则编译器不会为 GPU 生成正确的设备代码。

于 2013-01-31T08:36:47.143 回答