CUDA進階第六篇-GPU資源(視訊記憶體、控制代碼等)管理
阿新 • • 發佈:2019-02-09
最近在加速一個影象演算法,符合《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相關外包(除錯、優化、開發影象演算法等),有意向請聯絡,加好友時請註明