0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

使用OpenCV中的universal intrinsics為算法提速 (三)

電子設(shè)計(jì) ? 來(lái)源:電子設(shè)計(jì) ? 作者:電子設(shè)計(jì) ? 2020-12-10 19:40 ? 次閱讀
本文作者:于仕琪(OpenCV團(tuán)隊(duì))

OpenCV 4.x中提供了強(qiáng)大的統(tǒng)一向量指令(universal intrinsics),使用這些指令可以方便地為算法提速。所有的計(jì)算密集型任務(wù)皆可使用這套指令加速,非計(jì)算機(jī)視覺(jué)算法也可。目前OpenCV的代碼加速實(shí)現(xiàn)基本上都基于這套指令。

前序文章:
使用OpenCV中的universal intrinsics為算法提速 (1)
使用OpenCV中的universal intrinsics為算法提速 (2)

前序文章1介紹了怎么編寫(xiě)C語(yǔ)言代碼使用OpenCV中的universal intrinsics來(lái)加速;文章2介紹了編譯器的選項(xiàng)。

本文使用一個(gè)向量點(diǎn)乘的例子,來(lái)展示universal intrinsics的的提速。

我們有兩個(gè)向量vec1和vec2,將對(duì)應(yīng)元素相乘,然后累加起來(lái)。計(jì)算公式為:

sum=vec1[0]*vec2[0] + vec1[1]*vec2[1]+ ... + vec1[n]*vec2[n].

如果采用純C語(yǔ)言,兩個(gè)行向量的點(diǎn)乘實(shí)現(xiàn)如下(如代碼顯示不完整,可以左右滑動(dòng);或橫屏閱讀)

float dotproduct_c_float(Mat vec1, Mat vec2)
{
    float * pV1 = vec1.ptr(0);
    float * pV2 = vec2.ptr(0);
    float sum = 0.0f;
    for (size_t c = 0; c < vec1.cols; c++)
    {
        sum += pV1[c] * pV2[c];            
    }
    return sum;
}

如果采用OpenCV的universal intrinsics,兩個(gè)行向量的點(diǎn)乘實(shí)現(xiàn)如下:

(注意:下面函數(shù)僅為展示原理,未考慮數(shù)組長(zhǎng)度不是16(32或64)字節(jié)倍數(shù)情況)

float dotproduct_simd_float(Mat vec1, Mat vec2)
{
    float * pV1 = vec1.ptr(0);
    float * pV2 = vec2.ptr(0);
    size_t step = sizeof(v_float32)/sizeof(float);

    //向量元素全部初始化為零
    v_float32 v_sum = vx_setzero_f32();
    for (size_t c = 0; c < vec1.cols; c+=step)
    {
        v_float32 v1 = vx_load(pV1+c);
        v_float32 v2 = vx_load(pV2+c);
        //把乘積累加
        v_sum += v1 * v2; 
    }
    //把向量里的所有元素求和
    float sum = v_reduce_sum(v_sum);

    return sum;
}

例程使用OPEN AI LAB的EAIDK-310開(kāi)發(fā)板,OpenCV4.2.0,CPU型號(hào)為是RK3228H,采用ARM四核64位處理器 ,四核Cortex-A53,最高1.3GHz。

兩個(gè)例子的編譯命令分別如下(注意:皆采用了-O3選項(xiàng)以提速):

g++ dotproduct-c.cpp -o dotproduct-c -O3 -I/usr/local/include/opencv4 -lopencv_core
g++ dotproduct-simd.cpp -o dotproduct-simd -O3 -I/usr/local/include/opencv4 -lopencv_core

從兩個(gè)函數(shù)的耗時(shí)可以看出,采用OpenCV的universal intrinsics后耗時(shí)僅為一半,速度翻倍。

兩個(gè)例程的完整源代碼如下。首先是C語(yǔ)言版本的dotproduct-c.cpp:


#include 

using namespace cv;

float dotproduct_c_float(Mat vec1, Mat vec2)
{
    float * pV1 = vec1.ptr(0);
    float * pV2 = vec2.ptr(0);
    float sum = 0.0f;
    for (size_t c = 0; c < vec1.cols; c++)
    {
        sum += pV1[c] * pV2[c];            
    }
    return sum;
}

int main(int argc, char ** argv)
{

    Mat vec1(1, 16*1024*1024, CV_32FC1);
    Mat vec2(1, 16*1024*1024, CV_32FC1);

    vec1.ptr(0)[2]=3.3f;
    vec2.ptr(0)[2]=2.0f;

    double t = 0.0;
    t = (double)getTickCount();

    float sum = dotproduct_c_float(vec1, vec2);

    t = ((double)getTickCount() - t) / (double)getTickFrequency() * 1000; 
    printf("C time = %gms/n", t);
    printf("sum=%g/n", sum);

    return 0;
}

dotproduct-simd.cpp如下:

#include 
#include 
#include 
using namespace cv;

float dotproduct_simd_float(Mat vec1, Mat vec2)
{
    float * pV1 = vec1.ptr(0);
    float * pV2 = vec2.ptr(0);
    size_t step = sizeof(v_float32)/sizeof(float);

    //向量元素全部初始化為零
    v_float32 v_sum = vx_setzero_f32();
    for (size_t c = 0; c < vec1.cols; c+=step)
    {
        v_float32 v1 = vx_load(pV1+c);
        v_float32 v2 = vx_load(pV2+c);
        //把乘積累加
        v_sum += v1 * v2; 
    }
    //把向量里的所有元素求和
    float sum = v_reduce_sum(v_sum);

    return sum;
}

int main(int argc, char ** argv)
{

    Mat vec1(1, 16*1024*1024, CV_32FC1);
    Mat vec2(1, 16*1024*1024, CV_32FC1);

    vec1.ptr(0)[2]=3.3f;
    vec2.ptr(0)[2]=2.0f;

    double t = 0.0;
    t = (double)getTickCount();

    float sum = dotproduct_simd_float(vec1, vec2);

    t = ((double)getTickCount() - t) / (double)getTickFrequency() * 1000; 
    printf("SIMD time = %gms/n", t);

    printf("sum=%g/n", sum);

    return 0;
}

OpenCV中國(guó)團(tuán)隊(duì)由深圳市人工智能機(jī)器人研究院支持,是一個(gè)非營(yíng)利的開(kāi)源團(tuán)隊(duì),致力于OpenCV的開(kāi)發(fā)、維護(hù)和推廣工作。

獲取OpenCV最新動(dòng)態(tài),長(zhǎng)按下方二維碼關(guān)注

本文轉(zhuǎn)載自公眾號(hào): OpenCV團(tuán)隊(duì)

審核編輯 黃昊宇
聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 人工智能
    +關(guān)注

    關(guān)注

    1789

    文章

    46663

    瀏覽量

    237098
  • OpenCV
    +關(guān)注

    關(guān)注

    29

    文章

    625

    瀏覽量

    41215
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    intrinsics.h出錯(cuò)問(wèn)題

    在iccavr運(yùn)行,出現(xiàn)cannot #include file "intrinsics.h", file not found,請(qǐng)問(wèn)要怎么解決?求原因和方法
    發(fā)表于 09-20 10:00

    【NanoPi NEO試用體驗(yàn)】OpenCV使用篇

    opencv”和“opencv2”兩個(gè)文件夾,文件夾一些頭文件,在編寫(xiě)程序的時(shí)候需要用到。、軟件編寫(xiě)1.
    發(fā)表于 12-03 20:56

    新手求助,HLS實(shí)現(xiàn)opencv算法加速的IP在vivado的使用

    我照著xapp1167文檔,用HLS實(shí)現(xiàn)fast_corners的opencv算法,并生成IP。然后想把這個(gè)算法塞到第季的CH05_AXI_DMA_OV5640_HDMI上,這個(gè)de
    發(fā)表于 01-16 09:22

    基于QT+OpenCv的目標(biāo)跟蹤算法實(shí)現(xiàn)

    視頻目標(biāo)跟蹤,本文將首先向大家介紹常用的粒子濾波視頻目標(biāo)跟蹤算法,對(duì)其原理進(jìn)行簡(jiǎn)單的分析,后續(xù)進(jìn)一步選擇和應(yīng)用算法實(shí)現(xiàn)目標(biāo)跟蹤提供基礎(chǔ)。一、機(jī)器視覺(jué)及相關(guān)理論及OpenCv 機(jī)器視覺(jué)
    發(fā)表于 09-21 10:42

    OpenCV自帶組件HighGUI怎么使用?

    將介紹OpenCV自帶組件HighGUI的簡(jiǎn)單使用。當(dāng)我們?cè)跍y(cè)試算法,查看算法效果的時(shí)候,需要用到可視化,動(dòng)態(tài)調(diào)參的界面,也可能需要監(jiān)聽(tīng)鼠標(biāo),鍵盤(pán)等的動(dòng)作,這時(shí),HighGUI就發(fā)揮
    發(fā)表于 11-05 06:54

    移植OpenCV-4.3.0的過(guò)程

    OpenCV-4.3.0是較新的OpenCV版本,最新的版本是OpenCV-4.4.0,由于GitHub太慢總是下載失敗,不得已就移植OpenCV-4.3.0這個(gè)版本用著先。在
    發(fā)表于 11-04 08:51

    NEON匯編與NEON intrinsics編程的優(yōu)缺點(diǎn)比較

    的硬件資源不同,即使用intrinsics,有時(shí)我們也需要兩套代碼。Ne10FFT實(shí)現(xiàn)就是一個(gè)例子:上述代碼描述了32位浮點(diǎn)復(fù)數(shù)FFT算法的基本元——基4蝶形運(yùn)算。從代碼我們可以看
    發(fā)表于 03-30 10:46

    [譯]在RISC-V CPU上運(yùn)行OpenCV

    正在準(zhǔn)備推出。 盡管不同的CPU架構(gòu)具有不同的矢量指令,但OpenCV許多時(shí)間關(guān)鍵的內(nèi)核都使用我們自己的跨平臺(tái)Wide Universal Intrinsics進(jìn)行優(yōu)化——輕量級(jí)內(nèi)聯(lián)
    發(fā)表于 06-22 18:54

    openCV的庫(kù)自帶了模板匹配算法嗎?

    openCV的庫(kù)自帶了模板匹配算法
    發(fā)表于 10-10 06:48

    opencv 白平衡算法

    白平衡就是圖片中最亮的部分為白色,最暗的部分為黑色,其余部分進(jìn)行拉伸。下文將詳細(xì)介紹OpenCV實(shí)現(xiàn)的灰度世界算法
    發(fā)表于 01-17 09:05 ?7760次閱讀

    OpenCV白平衡算法之灰度世界法_OpenCV實(shí)現(xiàn)馬賽克和毛玻璃濾鏡效果

    OpenCV白平衡算法之灰度世界法(消除RGB受光照影響) 在用OpenCV對(duì)圖像進(jìn)行處理時(shí),利用顏色定位是常常會(huì)接觸到的方法,但RGB受光照影響比較嚴(yán)重,轉(zhuǎn)換到HSV XYZ等空間也解決不了
    發(fā)表于 01-17 09:34 ?6777次閱讀

    如何在OpenCV實(shí)現(xiàn)CUDA加速

    OpenCV4.x關(guān)于CUDA加速的內(nèi)容主要有兩個(gè)部分,第一部分是之前OpenCV支持的圖像處理與對(duì)象檢測(cè)傳統(tǒng)算法的CUDA加速;第二部分是Ope
    的頭像 發(fā)表于 09-05 10:03 ?4992次閱讀

    對(duì)比NEON匯編與NEON Intrinsics編程的優(yōu)缺點(diǎn)

    對(duì)于初學(xué)者來(lái)說(shuō),Intrinsics比較易學(xué)易用。但是對(duì)于有匯編經(jīng)驗(yàn)的開(kāi)發(fā)者來(lái)說(shuō),可能更熟悉NEON匯編編程,切換到Intrinsics反倒需要有個(gè)適應(yīng)過(guò)程。下文列出了實(shí)際開(kāi)發(fā)的一些問(wèn)題。
    的頭像 發(fā)表于 12-14 09:20 ?1149次閱讀

    OpenCV邊緣模板匹配算法原理詳解

    OpenCV自帶的模板匹配算法,完全是像素基本的模板匹配,特別容易受到光照影響,光照稍微有所不同,該方法就會(huì)歇菜了!搞得很多OpenCV初學(xué)者剛學(xué)習(xí)到該方法時(shí)候很開(kāi)心,一用該方法馬上
    的頭像 發(fā)表于 12-07 10:56 ?1289次閱讀
    <b class='flag-5'>OpenCV</b>邊緣模板匹配<b class='flag-5'>算法</b>原理詳解

    opencv圖像識(shí)別有什么算法

    OpenCV(Open Source Computer Vision Library)是一個(gè)開(kāi)源的計(jì)算機(jī)視覺(jué)和機(jī)器學(xué)習(xí)軟件庫(kù),提供了大量的圖像處理和計(jì)算機(jī)視覺(jué)相關(guān)的算法。以下是一些常見(jiàn)的OpenCV
    的頭像 發(fā)表于 07-16 10:40 ?748次閱讀