接下來再做乙個測試,將並行和序列的迴圈次數設定為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 ...