STL推力多向量变换?

Sha*_*pie 6 c++ stl cuda thrust

我想知道是否有更有效的方式来写a = a + b + c?

 thrust::transform(b.begin(), b.end(), c.begin(), b.begin(), thrust::plus<int>());
 thrust::transform(a.begin(), a.end(), b.begin(), a.begin(), thrust::plus<int>());
Run Code Online (Sandbox Code Playgroud)

这有效,但有没有办法只使用一行代码获得相同的效果?我查看了示例中的saxpy实现,但是它使用了2个向量和一个常量值;


这更有效吗?

struct arbitrary_functor
{
    template <typename Tuple>
    __host__ __device__
    void operator()(Tuple t)
    {
        // D[i] = A[i] + B[i] + C[i];
        thrust::get<3>(t) = thrust::get<0>(t) + thrust::get<1>(t) + thrust::get<2>(t);
    }
};


int main(){

     // allocate storage
    thrust::host_vector<int> A;
    thrust::host_vector<int> B;
    thrust::host_vector<int> C;

    // initialize input vectors
    A.push_back(10);
    B.push_back(10);
    C.push_back(10);

    // apply the transformation
    thrust::for_each(thrust::make_zip_iterator(thrust::make_tuple(A.begin(), B.begin(), C.begin(), A.begin())),
                     thrust::make_zip_iterator(thrust::make_tuple(A.end(),   B.end(),   C.end(),   A.end())),
                     arbitrary_functor());

    // print the output
       std::cout << A[0] << std::endl;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

Jar*_*ock 7

a = a + b + c算术强度低(每4个内存操作只有两个算术运算),因此计算将受到内存带宽限制.为了比较您提出的解决方案的效率,我们需要测量他们的带宽需求.

transform第一个解决方案中的每次调用都需要两次加载,每次调用需要一次存储plus.因此,我们可以模拟各自的成本transform呼叫3N,这里N是矢量的大小a,b和c.由于有两次调用transform,这个解决方案的成本是6N.

我们可以用同样的方式模拟第二种解决方案的成本.每次调用都arbitrary_functor需要三个负载和一个存储.因此,该解决方案的成本模型将是4N,这意味着for_each解决方案应该比调用transform两次更有效.当N大时,第二个解决方案应该6N/4N = 1.5x比第一个解决方案执行得更快.

当然,您可以始终以类似的方式结合zip_iterator使用transform,以避免两次单独调用transform.