交换CUDA推力设备向量,无记忆移动

时间:2017-10-05 05:19:28

标签: cuda thrust

如果我有两个cudaMalloc ed数组,我可以通过简单地交换相关指针来交换它们而不需要内存移动。

如果我有两个CUDA Thrust device_vectors,比如d_ad_b,我可以使用第三个临时向量交换它们,比如说d_c,但这需要记忆移动。

我的问题是:有没有办法在没有内存移动的情况下交换CUDA Thrust device_vectors?

2 个答案:

答案 0 :(得分:3)

不是我知道的。

没有暴露的构造函数接受现有的device_ptrdevice_vector中的基础基础向量是私有的,因此无法自己潜入并执行指针交换。在没有触发标准拷贝构造函数的情况下,这些是我能想到的唯一方法。

编辑添加,看起来这个答案是错误的。似乎最近(可能是推力1.6)的变化实现了一个内部指针交换机制,可以通过device_vector.swap()调用。这绕过了swap()的常用复制构造函数,并且不会触发内存传输

答案 1 :(得分:2)

似乎device_vector.swap()避免记忆运动。

确实,请考虑以下代码:

#include "cuda_runtime.h"
#include "device_launch_parameters.h"

#include <stdio.h>

#include <thrust\device_vector.h>

void printDeviceVector(thrust::device_vector<int> &d_a) {

    for (int k = 0; k < d_a.size(); k++) {

        int temp = d_a[k];
        printf("%i\n", temp);

    }

}

int main()
{
    const int N = 10;

    thrust::device_vector<int> d_a(N, 1);
    thrust::device_vector<int> d_b(N, 2);

    // --- Original
    printf("Original device vector d_a\n");
    printDeviceVector(d_a);
    printf("Original device vector d_b\n");
    printDeviceVector(d_b);

    d_b.swap(d_a);

    // --- Original
    printf("Final device vector d_a\n");
    printDeviceVector(d_a);
    printf("Final device vector d_b\n");
    printDeviceVector(d_b);

    d_a.clear();
    thrust::device_vector<int>().swap(d_a); 
    d_b.clear();
    thrust::device_vector<int>().swap(d_b);

    cudaDeviceReset();

    return 0;
}
使用

    d_b.swap(d_a);

如果我们对其进行分析,我们会在时间轴中看不到设备到设备的内存移动:

enter image description here

另一方面,如果我们将d_b.swap(d_a)更改为

d_b = d_a;

然后设备到设备的移动出现在时间轴中:

enter image description here

最后,时间显着支持d_b.swap(d_a),而不是d_b = d_a。对于N = 33554432,时间是

d_b.swap(d_a)     0.001152ms
d_b = d_a         3.181824ms