2013-05-05 86 views
8
  1. 似乎創建一個新的推力向量所有元素默認爲0 - 我只是想確認這將永遠是這種情況。如何避免thrust :: device_vector中元素的默認構造?

  2. 如果是這樣,也有辦法繞過構造負責此行爲額外的速度(因爲一些載體,我不需要他們有一個初始值,例如,如果他們的原始指針正在作爲輸出傳遞給CUBLAS)?

回答

7

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或更好。

+0

非常好。儘管之前爲stl編寫了調試分配器重載,但我忘記了最終的構造函數在這裏。應該繼續挖掘。 +1 :) – leander 2013-05-06 12:01:42

+0

其實 - 我很困惑。我的錯誤在於你的示例鏈中的「resize」屬於'insert',它又鏈接到'fill_insert',它又以'uninitialized_fill_n'結尾?因此,儘管在設置新的'storage_type'區域時可能會忽略'construct',您仍然可以獲取副本嗎? ......顯然我需要在調試器中逐步完成這個任務,但是我沒有看到如何避免默認/初始值爲'x'的默認arg中的最終'uninitialized_fill_n'。 – leander 2013-05-06 23:05:29

+0

您可能需要使用最新的Thrust調試器。這是一個複雜的調度。 – 2013-05-06 23:14:25