我正在优化pycuda /推力计划。在其中,我使用thrust::min_element来标识设备上数组中最小元素的索引。
使用Nvidia的可视化分析器,似乎每当我呼叫thrust::min_element
时,都会有一个DtoH(设备到主机)memcpy。我想要的是在设备上只进行 的一切。换句话说,min_element()的输出应存储在设备上,我可以在以后使用它,而不会花费小DtoH memcpy的成本。有没有办法做到这一点?还是我错误地思考问题?
我的尝试是在下面,其中的想法是将input_ptr
指向的数组中最小元素的索引放入output_ptr
指向的数组的第一个元素中。一切都应该在设备上完成,主机上没有任何东西。
此代码产生正确答案,但涉及不需要的memcpys。非常感谢您提供的任何帮助。
#include <thrust/extrema.h>
#include <thrust/device_vector.h>
#include <cuda.h>
void my_min_element(CUdeviceptr input_ptr, int length, CUdeviceptr output_ptr)
{
thrust::device_ptr<float> i_ptr((float*)input_ptr);
thrust::device_ptr<int> o_ptr((int*)output_ptr);
o_ptr[0] = thrust::distance(i_ptr,thrust::min_element(i_ptr, i_ptr+length));
}
答案 0 :(得分:1)
我找到了一个(令人失望的)回答我自己的问题:
我从CUDA开发团队的某人[链接]
中找到了这句话“我不是Thrust专家,所以请一定要反馈这些反馈;但我认为Thrust的这个设计元素值得重新审视。推力具有表现力和实用性,有时会因强调返回而受到破坏结果给了主机。我有很多场合我想严格在设备内存中进行操作,因此Thrust将值返回到主机内存的倾向实际上阻碍了;如果我想将结果返回给主机,我总是可以传入映射的设备指针(如果UVA生效,则表示由CUDA分配的任何主机指针)“
..所以看起来我可能运气不好。如果是这样,推力设计有什么缺陷!
答案 1 :(得分:-1)
我不确定你是否仍然对此感兴趣,但我相信我已经做了你想要它只是转换CUdeviceptr变量。 (并告诉使用该设备的推力)这里是减少,我相信推力不会做任何额外的副本:)
extern int GPUReduceCudaManage(CUdeviceptr d_data, unsigned int numElements)
{
thrust::plus<int> binary_op_plus;
int result = thrust::reduce(thrust::device,
(int*) d_data,
(int*) d_data + numElements,
0,
binary_op_plus);
return result;
}