Delphi 的平行計算

2021-07-30 10:43:37 字數 3760 閱讀 3716

所謂平行計算,可以讓一段**讓 cpu 的多個核同時開跑,非常明顯地提高**執行速度。

所謂「程式」,這個中文單詞,嚴格意義上來說,就是按照特定順序,一步一步地執行一些指令。這是標準的序列計算。序列計算的好處是有上下文依賴關係的事情,不會搞錯順序。好比先洗碗,再打飯,程式這樣寫了,計算機絕對不會搞錯成先打了飯吃完了才發現碗先沒洗導致肚子疼。

但很多時候,我們有大量資料需要計算,並且資料之間沒有前後依賴關係。比如:處理。我需要逐個畫素處理,但處理第乙個畫素和處理第二個畫素,沒有依賴關係。處理第一行和處理第二行,也沒有依賴關係。這時候,可以同時並行地處理。傳統做法是,我們寫乙個迴圈,一行一行的逐行處理;在一行中,我們寫個迴圈,乙個畫素乙個畫素地逐個處理。最終結果就是一張,我們是逐個畫素地處理。如果有 100 萬個畫素,就要迴圈 100 萬次。很消耗時間。

現代的 cpu,都是多核的。乙個迴圈跑下來,只使用了乙個核。其它幾個核都空閒著。平行計算的概念就是,把上面說的那種沒有先後依賴關係的資料處理,分到幾個核裡面同時處理。就好比有 12 個碗要洗,找乙個人來乙隻乙隻地洗,需要12分鐘;找4個人來一起洗,每個人只需要洗三個碗,洗完 12 個碗只需要3分鐘。

//這是計算一行的顏色值。其中 inputptr 是 rgb565 的資料在記憶體裡面的指標;colorptr 是 tbitmap 的 tbitmapdata 的指標。 

//btw: 以下**有點問題:顏色值可能搞錯,出來的結果,灰色正確,黃色變成了藍色。影象清晰度沒問題。

procedure tform1.convertoneline(const bmpwidth: integer; inputptr: pword;

colorptr: pbyte);

var col: integer;

color: word;

begin

for col := 1 to bmpwidth do

begin

color := inputptr^;

inc(inputptr);

colorptr^ := (( color and $1f) * $ff) div $1f;

inc(colorptr);

colorptr^ := (((color shr 5) and $3f) * $ff) div $3f;

inc(colorptr);

colorptr^ := (((color shr 11) and $1f) * $ff) div $1f;

inc(colorptr);

colorptr^ := $ff;

inc(colorptr);;

end;

end;

//以下**,有序列計算的**,也有平行計算的**,都測試通過。

procedure tform1.convertrgb565torgb8888(const bmpwidth, bmpheight: integer; rgb565dataptr: pword; bmpdata: tbitmapdata);

var inputpitch: integer;

row, col: integer;

color: word;

colorptr: pbyte;

inputptr: pword; // pointer to rgb565 data

begin

inputpitch:= bmpwidth*2;

//將下面的序列迴圈,改為並行迴圈,在4核手機上測試通過。

//大概比序列迴圈的時間少一半(並沒有少 1/4)。

tparallel.for(1, bmpheight, procedure(row: integer)

begin

inputptr:= pword(pbyte(rgb565dataptr) + (row-1)*inputpitch);

colorptr:= pbyte(bmpdata.data) + (bmpheight-row)*bmpdata.pitch;

self.convertoneline(bmpwidth, inputptr, colorptr);

end);

end;

//以下**是呼叫 convertrgb565torgb8888 的主程式:

procedure tform1.drawrgb656ontobmp;

var //直接將 rgb656 的資料畫到 bitmap 上去試試看:

abitmap: tbitmap;

bmpdata: tbitmapdata;

bmpwidth: integer;

bmpheight: integer;

rgb565dataptr, inputptr: pword; // pointer to rgb565 data

amemorystream: tmemorystream;

fn: string;

t: tdatetime;

inputpitch: integer;

row, col: integer;

color: word;

colorptr: pbyte;

begin

// 這段**的測試結果:1. 在安卓下,直接出現浮點運算異常錯誤;

//2. 在 windows 底下,執行完成,但沒有影象顯示。並且轉換過程耗時 200ms.跟蹤 scanlinetoalphacolor 函式內部,實際上是逐個點轉換為 rgb888

fn := memo1.lines.strings[0];

amemorystream := tmemorystream.create;

amemorystream.loadfromfile(fn);

try//abitmap := image1.bitmap;

bmpwidth:= 1280;

bmpheight:= 720;

image1.bitmap.setsize(bmpwidth, bmpheight);

rgb565dataptr := pword(nativeint(amemorystream.memory) + 66);

inputpitch:= bmpwidth*2; // bytes by row

t := now;

if image1.bitmap.map(tmapaccess.write, bmpdata) then //map 方法取得 bitmap 內部的資料結構,然後才能直接運算元據結構內部的指標。

tryself.convertrgb565torgb8888(bmpwidth, bmpheight, rgb565dataptr, bmpdata);

finally

image1.bitmap.unmap(bmpdata);

image1.updateeffects;

end;

memo1.lines.add('time consuming = ' + inttostr(millisecondsbetween(now, t)));

finally

amemorystream.free;

end;

end;

測試結果:

對720p 的 rgb565 轉碼為 rgba888,序列計算在 find5 手機上耗時58ms,平行計算耗時 32ms。

結論:delphi 的平行計算**,確實可以讓多個核同時跑起來,縮短計算時間。

python平行計算 python平行計算

0.基礎並行 發 multiprocessing threading 1.concurrent 2.併發 asynico 3.ipython下的平行計算 使用ipyparallel庫的ipython提供了前所未有的能力,將科學python的探索能力與幾乎即時訪問多個計算核心相結合。系統可以直觀地與本...

平行計算模型

平行計算模型通常指從並行演算法 的設計和分析出發,將各種並行計算機 至少某一類並行計算機 的基本特徵抽象出來,形成乙個抽象的計算模型。從更廣的意義上說,平行計算模型為平行計算提供了硬體和軟體介面 在該介面的約定下,並行系統硬體設計者和軟體設計 者可以開發對並行性 的支援機制,從而提高系統的效能。有幾...

平行計算模型

平行計算指的在同一時刻存在多於乙個計算任務被執行。由於cpu主頻提高的上限,使用多核心處理器進行平行計算早已成為主流。gpu也是乙個多核心的處理器,但它的平行計算模型與多核的cpu有很大區別。我們有必要了解gpu的並計算模型。對平行計算模式進行分類是了解cpu和gpu平行計算區別的有效方式。一種分類...