**
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 在這碰到了乙個很好的老師 當老師控制我的機器時 或者給我講題時 我都是很感動的 幾乎是每天都有問題 形成了依賴 以前他說不要一有問題就舉手問 我依然問 就算我不問他也會控制我的機器 看看我在做什麼 或者有什麼錯誤 現...