CUDA進階第六篇-GPU資源(顯存、句柄等)管理

最近在加速一個圖像算法,符合《CUDA進階第五篇-如何估算出程序的GPU加速比》中的第二種情況,程序由核函數和GPU API實現,但是資源管理特別差,顯存和句柄在程序中使用時才申請。每次函數執行都要申請和釋放一遍,非常耗費時間。


優化方案一:C++重構

我想到的第一個方案,就是C++重構,將所有的顯存和句柄定義爲成員變量,在構造函數中申請,析構函數中釋放。難度比較低,但是工作量比較大,因爲不同變量申請的顯卡大小不一樣,輸入圖像的大小是不一定的,所以對於每一個變量,必須申請足夠大的內存,而且這種情況下,如果發生顯存越界,則很難定位。而且參數名非常亂,着實費了一些勁才重構完。

優化方案二

因爲這個算法中變量比較多,重構完後,輸入大圖像果然出現顯存越界問題……真的是非常懶得去定位。某天靈光突現,可以用Tensorflow裏的顯存管理方式進行重構啊,先申請一塊非常大的顯存,程序中需要的時候直接分配即可。這樣可以最大程度上的少修改原代碼,並且可以有效的解決大圖像情況容易出現的顯存越界問題。詳細代碼如下。

class MemoryManagement
{
public:
    MemoryManagement(int workspace_total_size)
    {
        workspace_total_size_ = workspace_total_size;
        CUDA_CHECK(cudaMalloc(&workspace_, workspace_total_size_));

        init();
    }
    ~MemoryManagement()
    {
        CUDA_CHECK(cudaFree(workspace_));
    }

    void AllocateMemory(void **ptr, int size)
    {
        int cache_line_size = 4;
        int tmp_size = (size + cache_line_size) / cache_line_size * cache_line_size;
        workspace_used_size_ += tmp_size;

        assert(workspace_used_size_ <= workspace_total_size_);

        *ptr = (void*)workspace_ptr_;
        workspace_ptr_ += size;
    }

    void Reset()
    {
        init();
    }

protected:
    char *workspace_;
    char *workspace_ptr_;
    int workspace_total_size_;
    int workspace_used_size_;

    void init()
    {
        CUDA_CHECK(cudaMemset(workspace_, 0, workspace_total_size_));
        workspace_ptr_ = workspace_;
        workspace_used_size_ = 0;
    }
};

私人接各種CUDA相關外包(調試、優化、開發圖像算法等),有意向請聯繫,加好友時請註明


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章