一. 數(shù)據(jù)的存儲(chǔ)方式
對(duì)于一個(gè)矩陣,在內(nèi)存中有兩種存儲(chǔ)順序:(下面圖和表格摘自 https://en.wikipedia.org/wiki/Row-major_order)
對(duì)于下面的矩陣:
可以有兩種存儲(chǔ)方式:左為列優(yōu)先隘截,右為行優(yōu)先。
顧名思義峡钓,列優(yōu)先:優(yōu)先按列存儲(chǔ)结笨,先存完第一列再存第二列,行優(yōu)先同理憨琳。
C/C++中矩陣的存儲(chǔ)為行優(yōu)先物咳,但cublas/Matlab中是列優(yōu)先準(zhǔn)則锣险,在不同語(yǔ)言間讀取數(shù)據(jù)時(shí)需要注意這點(diǎn),同時(shí)在寫Matlab時(shí)要盡量取一個(gè)二維數(shù)組的列览闰,而不是行芯肤。
擴(kuò)展到N維矩陣,列優(yōu)先意味著存儲(chǔ)時(shí)第一個(gè)維度先變化压鉴,即存儲(chǔ)順序?yàn)?0,0,0,...)崖咨、(1,0,0,...)、(max,0,0,...)油吭、(0,1,0,...)击蹲、(1,1,0,...)署拟,
行優(yōu)先意味著最后一個(gè)維度先變化。
p.s:在處理數(shù)據(jù)時(shí)歌豺,說(shuō)明數(shù)據(jù)的順序需要表明:
? ? ? ? 1)維度安排?
? ? ? ? 2)是否是行\(zhòng)列優(yōu)先
這兩個(gè)信息缺一不可推穷。
p.s:caffe的Blob、numpy的array类咧、OpenCV的Mat都是和C語(yǔ)言一樣馒铃,是行優(yōu)先的。
p.s:貌似只有CUBLAS/Matlab中的矩陣是列優(yōu)先,Eigen默認(rèn)使用列優(yōu)先存儲(chǔ)痕惋,可以指定存儲(chǔ)方式区宇。
二. cublasSgemm的使用
在做人臉相似度比對(duì)時(shí),需要求解人臉特征與注冊(cè)人臉特征的余弦相似度值戳。當(dāng)注冊(cè)人連庫(kù)的規(guī)模達(dá)到百萬(wàn)千萬(wàn)的規(guī)模是該過(guò)程是很耗時(shí)的萧锉,我們可以采用GPU進(jìn)行優(yōu)化計(jì)算。優(yōu)化策略如下:
? ? ?1. 多batch
? ? ?2. 利用cublasgemm加速計(jì)算
假設(shè)一個(gè)batch的三個(gè)人臉特征如A矩陣所述述寡,人臉注冊(cè)庫(kù)特征如B所描述:
目標(biāo)求解:
轉(zhuǎn)化為:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? d=norm(A).norm(B)
矩陣norm(A):
矩陣norm(B):
由于cublas按照列優(yōu)先存儲(chǔ),那么數(shù)據(jù)放到cublas內(nèi)叶洞,如果我們?cè)俅伟凑瞻葱袃?yōu)先取出來(lái)鲫凶,那么我們會(huì)以為cublas對(duì)矩陣做了“轉(zhuǎn)置”運(yùn)算。
我們來(lái)看看caffe是怎么封裝的: