多核加速處理圖像


現在計算機的cpu一般都是多核的,而很多程序都沒有進行多核優化,這就沒有辦法充分利用cpu的性能了。

比如用vs2010中寫一個while(1)循環,在舊電腦上cpu運行是占100%的,而在新的4核電腦上運行則只占25%,似乎沒辦法再高了。

很多地方說用openmp可以發揮多核處理的能力,不過我在程序中加入openmp的優化指令后還是沒辦法運行到100%,也許是我哪里弄錯了。

因此,我這里沒有使用openmp,而是使用多線程的方式來進行運算加速。

比如要處理10000*10000像素的圖像,可以開四個線程,每一個線程分別處理2500*10000像素,這樣速度就能提高4倍了。

而試驗的效果也正好驗證了上面所說的方法,提高的速度非常接近4倍。

當然,如果是8核或16核,開8或16個線程,基本上就能提高8倍或16倍了。

圖像算法一般還是很容易寫成並行的,我這里用了freeimage圖像庫,cpu是i5 4590。

處理10000*10000的圖像,單線程用了3500ms左右,四線程用了900ms左右,基本上算提高4倍了。

程序也許可以開更多的線程,不過我還沒有嘗試。

代碼如下,功能就是顏色取反:

#include <iostream>
#include <Windows.h>
#include <process.h>
#include <time.h>
#include "FreeImage.h"
using namespace std;

//就設成全局變量吧 FREE_IMAGE_FORMAT fif; FIBITMAP
*img; FIBITMAP *re;
int h; int w; int bpp; void Init() { string name="img.jpg"; fif=FreeImage_GetFileType(name.c_str()); img=FreeImage_Load(fif,name.c_str()); h=FreeImage_GetHeight(img); w=FreeImage_GetWidth(img); bpp=FreeImage_GetBPP(img); re=FreeImage_Allocate(w,h,bpp); } void Calc(int ymin,int ymax) { for (int y=ymin;y<ymax;y++) { for (int x=0;x<w;x++) { RGBQUAD color; FreeImage_GetPixelColor(img,x,y,&color); color.rgbBlue-=255; color.rgbGreen-=255; color.rgbRed-=255; FreeImage_SetPixelColor(re,x,y,&color); } } } void CalcAll() { Calc(0,h); } //每個線程處理圖像的1/4 void Calc1(PVOID param) { Calc(0,int(h/4)); } void Calc2(PVOID param) { Calc(int(h/4),int(h/2)); } void Calc3(PVOID param) { Calc(int(h/2),int(3*h/4)); } void Calc4(PVOID param) { Calc(int(3*h/4),h); } void main() { double start,end; HANDLE hThread[4]; Init(); start=clock(); CalcAll(); end=clock(); cout<<end-start<<endl; start=clock(); hThread[0]=(HANDLE)_beginthread(Calc1,0,NULL); hThread[1]=(HANDLE)_beginthread(Calc2,0,NULL); hThread[2]=(HANDLE)_beginthread(Calc3,0,NULL); hThread[3]=(HANDLE)_beginthread(Calc4,0,NULL); WaitForMultipleObjects(4,hThread,true,INFINITE); end=clock(); cout<<end-start<<endl; FreeImage_Unload(img); FreeImage_Unload(re); system("pause"); }

 后記:

我又測試了一下,電腦是可以使用openmp加速的,需要打開vs2010 openmp優化選項,然后把Calc()函數改成如下形式就行了:

void Calc(int ymin,int ymax)
{
    RGBQUAD color;
    #pragma omp parallel for schedule(dynamic, 1) private(color)   
    for (int y=ymin;y<ymax;y++)
    {
        for (int x=0;x<w;x++)
        {

            FreeImage_GetPixelColor(img,x,y,&color);
            color.rgbBlue-=255;
            color.rgbGreen-=255;
            color.rgbRed-=255;
            FreeImage_SetPixelColor(re1,x,y,&color);
        }
    }
}

速度比自己寫的多線程還快。

后后記:

最后我還是建議用自己寫的多線程,不建議使用openMP,因為使用openMP處理后圖像會產生很多麻點,這是不可接受的,就像下面一樣:

使用自己控制的多線程則不存在這樣的問題。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM