並行數目與並形體對執行效率的影響

2021-06-02 04:31:14 字數 4406 閱讀 5653

接下來再做乙個測試,將並行和序列的迴圈次數設定為100,即將上例的main函式中:

for(int i = 0; i < 10000;i++)

更改為:

for(int i = 0; i < 100;i++)

然後分別執行10次,其結果如下表所示:

次數序列並行1

0.00285003

0.007350087

20.00288031

0.00385478

30.0028603

0.00231841

40.00275407

0.0092762

50.00280949

0.00980167

60.00281462

0.00538499

70.00286081

0.00538858

80.00281103

0.00424682

90.00281309

0.00892829

100.00280026

0.00370494

平均值0.002825401

0.006025477

從上面的分析結果可見,在迴圈100次的時候,只有極少數情況下平行計算比序列計算所需的時間要少,許多情況下並行需要更多的時間,這與我們設計並行程式的初衷是截然相反的。出現這種情況的原因之一就是,在分發並行的時候,系統也是需要消耗資源的,如果用於並行分發所耗的時間大於平行計算中節約的時間,那麼這種情況下的平行計算就顯得毫無意義,正如上例中的測試。所以,在平行計算中,並不是所有的平行計算都比序列計算要節約時間,具體要看並行的任務是否值得去做平行計算。還有乙個重要的原因就是每次並行的執行緒數目,由於計算機cpu同時支援的並行執行緒有限,不可能指定並行100次, cpu在同一時刻就能執行100個執行緒。另外,由於這個比較程式的計算量非常小,很容易受到系統中其他因素的影響而導致計算結果的不穩定,所以,建議在進行測試時,盡量將計算量稍微調大一點,同時每次測試時應盡量保證執行環境相近,以減少系統中其他程式對測試結果的干擾。

下面用乙個例子更能說明並行數目與程式執行效率間的關係,設定並形體中的計算量都一樣,每次只是並行的次數不同,具體**如下:

//file: test02.cpp

#include "stdafx.h"

#include

#include

using namespace std;

//迴圈測試函式

void test02()

for(inti=0;i<5000000;i++)

for(intj=0;j<1000;j++);

int main()

cout<

cout<

intn=1;

cin>>n;

cout<

doublestart = omp_get_wtime( );//獲取起始時間

#pragmaomp parallel for

for(inti = 0; i < n; i++)

test02();

doubleend = omp_get_wtime( );//獲取結束時間

cout<>end;

return0;

在近似的測試環境中分別對並行1次(相對於序列)、2次、3次等引數進行測試,其結果如下表:

n計算耗時(s)

n計算耗時(s)

113.3731

1227.526

213.343

1328.9753

313.2072

1428.0228

413.7742

1529.4308

513.5256

1628.5016

614.0692

1741.1712

714.4321

1841.3934

815.2443

2447.6976

927.5141

2555.7176

1028.201

3260.9475

1129.0979

3369.7519

計算時間與並行次數之間的關係如下圖所示:

從以上分析結果可知,在並形體中計算量相同的情況下,在計算機cpu物理執行緒數目以內的並行次數可以得到更好的效果。這也可以很好的解釋並行中線程數目設定的限制問題,如當設定9個並行執行緒時,由於計算機最多隻支援8個執行緒,那第9個執行緒理所當然就不能和前面8個執行緒處於同一起跑線,它只能排在這8個執行緒的後面。假定第1到第8個執行緒是處於第一排,這一排的8個執行緒將會同時起步執行,而第9個到第16個處於第二排,它們則要在第一排後面起步,依次類推。每一時刻,都只會有8個執行緒在進行計算,而並行的結束是以所有的執行緒執行結束為標誌,因此,最後那個執行緒(或者說最慢的那個執行緒)將決定並行結束的時間,所以執行緒越多,那麼排隊就越長,並行結束的時間相應就會增長。當然,具體一隊中有多少個迴圈,可以通過schedule來設定,關於schedule後面將會詳細介紹。

當然,上面的分析是基於並形體中計算量相同的前提,但有些情況下並形體的計算量與並行次數有著密切關係,譬如說總計算量一定的情況下,任何設定合理的並行次數對整個程式的執行起著至關重要的作用。如下例子,平行計算的總計算量一定,即如果設定並行次數越多,則並形體中的計算量越小。**如下:

//file: test03.cpp

#include "stdafx.h"

#include

#include

using namespace std;

//迴圈測試函式

void test03(int space)

for(inti=0;ifor(intj=0;j<1000;j++);

int main()

inttotal=36288000;

cout<

cout<

intn=1;

cin>>n;

intspace =total/n;

cout<

doublestart = omp_get_wtime( );//獲取起始時間

#pragmaomp parallel for

for(inti = 0; i < n; i++)

test03(space);

doubleend = omp_get_wtime( );//獲取結束時間

cout<>end;

return0;

分別設定並行次數從1到42進行測試,測試結果如下表所示:

n計算耗時

n計算耗時

n計算耗時

n計算耗時

196.9828

1414.3488

2714.9022

4012.8593

247.2697

1513.7259

2814.3302

4114.7085

331.8575

1612.8605

2914.0329

4214.3195

423.5635

1717.213

3013.6062

5014.2404

519.2746

1816.551

3113.1146

6013.5563

616.7957

1915.819

3212.8218

8012.8094

714.2741

2014.9696

3315.0214

10013.2439

812.8982

2114.3318

3414.7972

20012.8838

921.3869

2213.8786

3514.4498

40012.8444

1019.7044

2313.3461

3614.0154

1000

12.8158

1117.9848

2412.9017

3713.7218

2000

12.7411

1216.4976

2515.9088

3813.3481

1314.5436

2615.5088

3913.0619

比較結果如下圖所示:

由上圖中可以很明顯的看出,當並行數目達到計算機cpu最多執行緒數目時(測試計算機上cpu支援8執行緒),其計算效率將達到比較好的效果。假定計算機支援的最多執行緒為n,並行數目在0~n之間,計算效率逐漸增加,達到n時效率極高,當增加到n+1個並行數目時,計算效率會驟降,但在n+1與2n之間,計算效率同樣也會逐漸增加,當達到2n+1時,又會驟降,隨著並行數目不斷增加,該規律將會不斷的重現。

所以,綜合以上兩個測試例子也不難發現,並非並行數目越多,其計算效率就越高,具體效率跟程式結構以及計算機有著密切的聯絡。

C Excel匯出合併行和列並動態載入行與列

簡單的excel匯出比較好做,只要設定表頭,迴圈在 中賦值新增資料即可,但是如果表頭是不固定的,並且個數是不確定的,這就需要根據查詢出資料的特點來新增匯出了。如上圖所示,商品的個數是不確定的,時間的月份個數也是不確定的,所以簡單的通過模板是不可以的。並且資料庫中查詢出的資訊是每個商品不同時間的資訊,...

pandas進行資料的交集與並集方式的資料合併

資料合併有多種方式,其中最常見的應該就是交集和並集的求取。之前通過分析總結過 pandas 資料merge 功能預設的行為,其實預設下求取的就是兩個資料的 交集 有如下資料定義 in 26 df1 out 26 data1 key 0 0 b 1 1 b 2 2 a 3 3 c 4 4 a 5 5 ...