8
似乎创建一个新的推力向量所有元素默认为0 - 我只是想确认这将永远是这种情况。如何避免thrust :: device_vector中元素的默认构造?
如果是这样,也有办法绕过构造负责此行为额外的速度(因为一些载体,我不需要他们有一个初始值,例如,如果他们的原始指针正在作为输出传递给CUBLAS)?
似乎创建一个新的推力向量所有元素默认为0 - 我只是想确认这将永远是这种情况。如何避免thrust :: device_vector中元素的默认构造?
如果是这样,也有办法绕过构造负责此行为额外的速度(因为一些载体,我不需要他们有一个初始值,例如,如果他们的原始指针正在作为输出传递给CUBLAS)?
thrust::device_vector
构建它包含使用其提供的分配器,就像std::vector
的元素。当向量要求它构造一个元素时,可以控制分配器执行的操作。
使用自定义分配器,以避免向量元素的默认初始化:
// uninitialized_allocator is an allocator which
// derives from device_allocator and which has a
// no-op construct member function
template<typename T>
struct uninitialized_allocator
: thrust::device_malloc_allocator<T>
{
// note that construct is annotated as
// a __host__ __device__ function
__host__ __device__
void construct(T *p)
{
// no-op
}
};
// to make a device_vector which does not initialize its elements,
// use uninitialized_allocator as the 2nd template parameter
typedef thrust::device_vector<float, uninitialized_allocator<float> > uninitialized_vector;
你仍然招致内核启动成本来调用uninitialized_allocator::construct
,但内核将是一个空操作,这将退休很快。你真正感兴趣的是避免填充阵列所需的内存带宽,这个解决方案就是这样。
有一个完整的示例代码here。
请注意,此技术需要推力1.7或更好。
非常好。尽管之前为stl编写了调试分配器重载,但我忘记了最终的构造函数在这里。应该继续挖掘。 +1 :) – leander 2013-05-06 12:01:42
其实 - 我很困惑。我的错误在于你的示例链中的“resize”属于'insert',它又链接到'fill_insert',它又以'uninitialized_fill_n'结尾?因此,尽管在设置新的'storage_type'区域时可能会忽略'construct',您仍然可以获取副本吗? ......显然我需要在调试器中逐步完成这个任务,但是我没有看到如何避免默认/初始值为'x'的默认arg中的最终'uninitialized_fill_n'。 – leander 2013-05-06 23:05:29
您可能需要使用最新的Thrust调试器。这是一个复杂的调度。 – 2013-05-06 23:14:25