在 cuda 中使用 thrust experimental::pinned_allocator 的奇怪行为
Weird behaviour using thrust experimental::pinned_allocator in cuda
我目前正在尝试从我的代码中删除部分繁琐的 cudaMallocHost/cudaFreeHost。为此,我愿意只使用std::vector,但我绝对需要底层内存必须是pinned cuda内存类型。
但是,我在使用 thrust 库中的 thrust::system::cuda::experimental::pinned_allocator<>
时遇到了奇怪的行为:
//STL
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
//CUDA
#include <cuda_runtime.h>
#include <thrust/device_vector.h>
#include <thrust/transform.h>
#include <thrust/system/cuda/experimental/pinned_allocator.h>
#define SIZE 4
#define INITVAL 2
#define ENDVAL 4
//Compile using nvcc ./main.cu -o test -std=c++11
int main( int argc, char* argv[] )
{
// init host
std::vector<float,thrust::system::cuda::experimental::pinned_allocator<float> > hostVec(SIZE);
std::fill(hostVec.begin(),hostVec.end(),INITVAL);
//Init device
thrust::device_vector<float> thrustVec(hostVec.size());
//Copy
thrust::copy(hostVec.begin(), hostVec.end(), thrustVec.begin());
//std::cout << "Dereferencing values of the device, values should be "<< INITVAL << std::endl;
std::for_each(thrustVec.begin(),thrustVec.end(),[](float in){ std::cout <<"val is "<<in<<std::endl;} );
std::cout << "------------------------" << std::endl;
//Do Stuff
thrust::transform( thrustVec.begin(), thrustVec.end(), thrust::make_constant_iterator(2), thrustVec.begin(), thrust::multiplies<float>() );
//std::cout << "Dereferencing values of the device, values should now be "<< ENDVAL << std::endl;
std::for_each(thrustVec.begin(),thrustVec.end(),[](float in){ std::cout <<"val is "<<in<<std::endl;} );
std::cout << "------------------------" << std::endl;
//Copy back
thrust::copy(thrustVec.begin(), thrustVec.end(), hostVec.begin());
//Synchronize
//cudaDeviceSynchronize(); //makes the weird behaviour to go away
//Check result
//std::cout << "Dereferencing values on the host, values should now be "<< ENDVAL << std::endl;//Also makes the weird behaviour to go away
std::for_each(hostVec.begin(),hostVec.end(),[](float in){ std::cout <<"val is "<<in<<std::endl;} );
return EXIT_SUCCESS;
}
在我的设置中,它给出了:
val is 2
val is 2
val is 2
val is 2
------------------------
val is 4
val is 4
val is 4
val is 4
------------------------
val is 2
val is 4
val is 4
val is 4
为什么从设备到主机的复制似乎失败了?然而,Nvvp 显示了一个完美的计时图,具有正确的复制值。
顺便说一下,我使用 7.5 包中的 NVCC/cuda/thrust,以及带有 titanX 卡的 gcc (GCC) 4.8.5。
预先感谢您的帮助。
这是一个真正的大问题,thrust 开发人员已经意识到这一点,请参阅 https://github.com/thrust/thrust/issues/775
使用 github 存储库中的最新 1.8.3 版 thrust 解决了我的问题。
我目前正在尝试从我的代码中删除部分繁琐的 cudaMallocHost/cudaFreeHost。为此,我愿意只使用std::vector,但我绝对需要底层内存必须是pinned cuda内存类型。
但是,我在使用 thrust 库中的 thrust::system::cuda::experimental::pinned_allocator<>
时遇到了奇怪的行为:
//STL
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
//CUDA
#include <cuda_runtime.h>
#include <thrust/device_vector.h>
#include <thrust/transform.h>
#include <thrust/system/cuda/experimental/pinned_allocator.h>
#define SIZE 4
#define INITVAL 2
#define ENDVAL 4
//Compile using nvcc ./main.cu -o test -std=c++11
int main( int argc, char* argv[] )
{
// init host
std::vector<float,thrust::system::cuda::experimental::pinned_allocator<float> > hostVec(SIZE);
std::fill(hostVec.begin(),hostVec.end(),INITVAL);
//Init device
thrust::device_vector<float> thrustVec(hostVec.size());
//Copy
thrust::copy(hostVec.begin(), hostVec.end(), thrustVec.begin());
//std::cout << "Dereferencing values of the device, values should be "<< INITVAL << std::endl;
std::for_each(thrustVec.begin(),thrustVec.end(),[](float in){ std::cout <<"val is "<<in<<std::endl;} );
std::cout << "------------------------" << std::endl;
//Do Stuff
thrust::transform( thrustVec.begin(), thrustVec.end(), thrust::make_constant_iterator(2), thrustVec.begin(), thrust::multiplies<float>() );
//std::cout << "Dereferencing values of the device, values should now be "<< ENDVAL << std::endl;
std::for_each(thrustVec.begin(),thrustVec.end(),[](float in){ std::cout <<"val is "<<in<<std::endl;} );
std::cout << "------------------------" << std::endl;
//Copy back
thrust::copy(thrustVec.begin(), thrustVec.end(), hostVec.begin());
//Synchronize
//cudaDeviceSynchronize(); //makes the weird behaviour to go away
//Check result
//std::cout << "Dereferencing values on the host, values should now be "<< ENDVAL << std::endl;//Also makes the weird behaviour to go away
std::for_each(hostVec.begin(),hostVec.end(),[](float in){ std::cout <<"val is "<<in<<std::endl;} );
return EXIT_SUCCESS;
}
在我的设置中,它给出了:
val is 2
val is 2
val is 2
val is 2
------------------------
val is 4
val is 4
val is 4
val is 4
------------------------
val is 2
val is 4
val is 4
val is 4
为什么从设备到主机的复制似乎失败了?然而,Nvvp 显示了一个完美的计时图,具有正确的复制值。
顺便说一下,我使用 7.5 包中的 NVCC/cuda/thrust,以及带有 titanX 卡的 gcc (GCC) 4.8.5。
预先感谢您的帮助。
这是一个真正的大问题,thrust 开发人员已经意识到这一点,请参阅 https://github.com/thrust/thrust/issues/775
使用 github 存储库中的最新 1.8.3 版 thrust 解决了我的问题。