cuda第一次計算耗時 nms的cuda實現解析

2021-10-17 08:23:57 字數 2633 閱讀 1567

**

nms是不太好在cuda上實現的,因為nms的計算過程是有依賴關係的,比如a,b,c三個置信度由大到小的檢測框,如果iou(a,b)大於閾值,那麼bc的iou則不必再計算了,由於依賴關係會限制cuda的發揮,因此cuda實現中,所有的box之間的iou都是需要計算的,不過有的結果是不需要的。

**中nms的輸出是長度為

bool dev_mask[boxes_num][boxes_num];

// nms kernel ...

bool mask[boxes_num];

for (int i = 0; i < boxes_num; ++i)

}

作者用unsigned long long則是將64位的unsigned long long的每乙個bit當做乙個box的結果,bit位1則刪除,為0則保留,dev_mask變為

再來看看作者的實現

int const threadsperblock = sizeof(unsigned long long) * 8;

const int col_blocks = divup(boxes_num, threadsperblock);

std::vectorremv(col_blocks);

memset(&remv[0], 0, sizeof(unsigned long long) * col_blocks);

int num_to_keep = 0;

for (int i = 0; i < boxes_num; i++) }}

再來看看nms kernel的實現,首先kernel的grid是2d的,block是1d的

dim3 blocks(divup(boxes_num, threadsperblock),

divup(boxes_num, threadsperblock));

dim3 threads(threadsperblock);

nms_kernel<<>>(boxes_num,

nms_overlap_thresh,

boxes_dev,

mask_dev);

其中每乙個thread計算dev_mask中的乙個值,可以通過乙個示意圖更好地理解並行的邏輯

其中第i行的block計算以第

block(0,0) 計算[0,threadsperblock](基準) x [0,threadsperblock](其他)的dev_mask

block(0,1) 計算[0,threadsperblock] x [threadsperblock,threadsperblock*2]的dev_mask

block(0,2) 計算[0,threadsperblock] x [threadsperblock*2,threadsperblock*3]的dev_mask

block(i,j) 計算

[i*threadsperblock, (i+1)*threadsperblock](基準)x [j*threadsperblock,(j+1)*threadsperblock](其他)的devmask結果,如果把dev_mask看成二維陣列更好理解,dev_mask的第一維是基準box的索引,第二維是其他box的索引

更新:

從更簡單的形式開始分析會更好理解,比如只有乙個block,block的大小是2d的,為nxn,n為檢測框數量,假設n=6,並行邏輯如下圖

每個thread計算一對box的iou(只用計算上三角部分)作者的實現則是將6x6的分成3x3的小block,每個block的thread為2,即

這樣做的好處是減少cuda資源占用,原來需要36個thread,現在只要18個thread(每個thread要計算2對box的iou)並且每個小的block的其他box可以存入共享記憶體,減少全域性記憶體的訪問

__global__ void nms_kernel(const int n_boxes, const float nms_overlap_thresh,

const float *dev_boxes, unsigned long long *dev_mask)

__syncthreads();

if (threadidx.x < row_size)

// 遍歷其他box,計算當前基準box和其他box的iou,如果大於nms閾值,則置對應的位為1,即刪除

for (i = start; i < col_size; i++)

}const int col_blocks = divup(n_boxes, threadsperblock);

// 結果寫入dev_mask

dev_mask[cur_box_idx * col_blocks + col_start] = t;

}}

第一次飛行

開始敲下這段話時,窗外下面正是一片片陽光照耀著的白雲,伴隨著張學友的歌聲,心潮起伏.雖然從初中起,我就經常乙個人坐著火車,汽車東奔西跑,坐飛機卻是第一次.早上上飛機前,心裡忐忑,必竟還是踏在陸地上踏實.但上了飛機後注意力就放在其它地方上去了,而且,運氣好的是我有乙個靠窗的位置.飛機準備起飛了,助跑加...

第一次面試

話說3月4號學院召開實習動員大會並有三家公司過來進行宣講會,分別是國家體育總局亞運專案組,金蝶和華際友天,由此開始了實習生涯。周五的傍晚,正吃著飯的時候突然收到簡訊通知,金蝶週六上午10點有個面試。當晚就瀏覽著些簡歷製作相關的網頁,為第二天做準備,總以為,簡歷弄得可以了,然後每太留意去完善 後來才知...

第一次哭泣

第一次來到南方 沒有朋友 沒有親人 乙個從沒有出過門的乙個女孩子 為了工作 學習c 在這碰到了乙個很好的老師 當老師控制我的機器時 或者給我講題時 我都是很感動的 幾乎是每天都有問題 形成了依賴 以前他說不要一有問題就舉手問 我依然問 就算我不問他也會控制我的機器 看看我在做什麼 或者有什麼錯誤 現...