我想学习如何使用CUDA与推力,我已经看到了一些代码,其中的printf函数似乎从设备使用。使用推力与printf/cout
考虑以下代码:
#include <thrust/host_vector.h>
#include <thrust/device_vector.h>
#include <cstdio>
struct functor
{
__host__ __device__
void operator()(int val)
{
printf("Call for value : %d\n", val);
}
};
int main()
{
thrust::host_vector<int> cpu_vec(100);
for(int i = 0 ; i < 100 ; ++i)
cpu_vec[i] = i;
thrust::device_vector<int> cuda_vec = cpu_vec; //transfer to GPU
thrust::for_each(cuda_vec.begin(),cuda_vec.end(),functor());
}
这看上去一切正常,并打印100次消息“的价值呼唤:”后跟一个数字。
现在如果我有iostream的,用C++基于流的等效
std::cout << "Call for value : " << val << std::endl;
我得到合辑NVCC警告和编译程序将不打印任何东西取代的printf线。
warning: address of a host variable "std::cout" cannot be directly taken in a device function
warning: calling a __host__ function from a __host__ __device__ function is not allowed
warning: calling a __host__ function("std::basic_ostream<char, std::char_traits<char> >::operator <<") from a __host__ __device__ function("functor::operator()") is not allowed
- 为什么它与printf的工作吗?
- 为什么它不是与cout一起工作?
- 实际在GPU上运行的是什么?我猜想,至少发送到标准输出需要一些CPU的工作。
'printf'作为'__device__'函数“重载”,而'cout'不是。您需要明确的“重载”打印功能,因为您需要正确处理输出缓冲区。看一看'simplePrintf'的例子,你会感觉到你为什么需要显式重载以及如何做到这一点。由于'cout'只是'__host__'函数,'nvcc'不能编译它。 – JackOLantern