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