在不移动内存的情况下交换CUDA推力装置矢量

在不移动内存的情况下交换CUDA推力装置矢量,cuda,thrust,Cuda,Thrust,如果我有两个cudamaloced数组,只需交换相关指针,就可以在不移动内存的情况下交换它们 如果我有两个CUDA推力装置矢量,比如d\u a和d\u b,我可以使用第三个临时矢量,比如d\u c,来交换它们,但这需要内存移动 我的问题是:有没有办法在没有记忆移动的情况下交换CUDA推力装置向量?我不知道 没有公开的构造函数接受现有的device_ptr,并且device_vector中的基础基向量是私有的,因此无法亲自深入并执行指针交换。这将是我能想到的唯一一种在不触发标准复制构造函数的情况下

如果我有两个
cudamaloc
ed数组,只需交换相关指针,就可以在不移动内存的情况下交换它们

如果我有两个CUDA推力装置矢量,比如
d\u a
d\u b
,我可以使用第三个临时矢量,比如
d\u c
,来交换它们,但这需要内存移动


我的问题是:有没有办法在没有记忆移动的情况下交换CUDA推力装置向量?

我不知道

没有公开的构造函数接受现有的
device_ptr
,并且
device_vector
中的基础基向量是私有的,因此无法亲自深入并执行指针交换。这将是我能想到的唯一一种在不触发标准复制构造函数的情况下实现此功能的方法


编辑以添加此答案似乎是错误的。最近(大概在1.6版前后)的变化似乎实现了一种内部指针交换交换机制,可以通过
device\u vector.swap()
调用该机制。这绕过了
swap()
常用的复制构造函数习惯用法,不会触发内存传输
.

似乎
设备\u 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\u b.swap(d\u a)
更改为

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

最后,时间安排明显有利于
dub.swap(dua)
,而不是
dub=dua
。对于
N=33554432
,正时为

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

如果您不知道,那么99.99%的可能性是不可能的:-)谢谢您,一如既往。考虑到这一点,您可能可以通过破解一个定制的分配器类来完成操作,该类返回另一个设备向量的内存。但是还有很多其他问题可能无法解决,比如一个问题:
d_b.swap(d_a)
是否意味着内存移动?我已经有一段时间没有看到这一点了,但我99%确信所有的struct中的swap都使用复制构造函数,而这会触发内存移动,我不能--AFAIK这是
swap
Just
temp=a;a=b;b=温度。这将导致内存移动
推力::向量
类有一个类型为
连续存储
的成员,用于存储向量内容。在内部交换向量时,只交换
连续存储
begin()
迭代器、
大小
分配器
。因此不涉及数据的内存拷贝。您可以在文件
continuous_storage.inl
中的成员函数中检查此项。对于赋值运算符,如果您查看的代码,它将使用
assign
函数,该函数似乎执行向量内容的完整内存复制。@sgarizvi感谢您的评论。事实上,这与@Talonmes在下面的评论中指出的反对意见相同。然而,奇怪的是,我在时间线中找不到内存副本。也许
stress
使用内核执行复制?@sgarizvi我在主代码中将显式复制替换为
swap
,在时间上有好处。至少,
swap
似乎比copy快。我认为这是vector类相对较新的特性。在过去,我很确定swap使用了拷贝分配,这触发了内存拷贝。
d_b.swap(d_a)     0.001152ms
d_b = d_a         3.181824ms