青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

Kisser Leon

這個kisser不太冷
posts - 100, comments - 102, trackbacks - 0, articles - 0

多線程計算PI碰到的問題

Posted on 2007-03-23 23:42 kk 閱讀(1970) 評論(3)  編輯 收藏 引用 所屬分類: IT

例子如下,用于計算 PI 的值。 gIterations 是計算 PI 的迭代次數, gThreadCount 是線程的個數。方法是這樣子的,把 PI 分成 gThreadCount 個段,分別讓一個線程來執行 PI 的求值操作。求得 PI 值有兩種方法,一種是直接把各個線程每一步所求得的值加到 gSum 上去,另一種是把各個線程所求得的值加到一個與之對應的全局變量中去。對每個線程 i ,輸出 Thread number:I aaaaaaaa ,表示線程開始執行,輸出 Thread number:I bbbbbbb 則表示線程執行完畢。有些地方還可以優化的,不過這里只是為了演示多線程的問題,所以就不予關注了。恩。

代碼如下。當只有一個 thread 的時候,結果是 OK 的( gSum==sum==3.14159* ,用等號有點問題,但是結果差異在十萬分之一以內)。當有三個 threads 的時候,問題就開始出現了! gSum 計算出來只有 2.* !怎么會這樣子呢?各位有興趣的話,可以運行下面的代碼試試看。接著看下面的分析。

#include <windows.h>

#include <stdio.h>

#include <time.h>

?

const int gIterations = 100000000;

const int gThreadCount = 3;

double gSum = 0.0;

double gPart[gThreadCount];

?

DWORD WINAPI threadFunction(LPVOID pArg)

{

??? int threadNum = (int)pArg;//starts from 0

??? printf("Thread number:%d: aaaaaaaaaaaa\n", threadNum);

??? for ( int i=threadNum; i<gIterations; i+=gThreadCount )

??? {

??????? double dx = (i + 0.5f) / gIterations;

??????? gSum += 4.0f / (1.0f + dx*dx);//cause problems here!

??????? gPart[threadNum] += 4.0f / (1.0f + dx*dx);

??? }

?

??? printf("part%d value:%.6f\n", threadNum, gPart[threadNum]/gIterations);

??? printf("Thread number:%d: bbbbbbbbbbbb\n", threadNum);

??? return 0;

}

?

int main()

{

??? memset(gPart, 0.0, sizeof(gPart)/sizeof(double));//init to 0

?

??? printf("Computing value of Pi: \n");

??? clock_t start = clock();

?

??? HANDLE threadHandles[gThreadCount];

??? for ( int i=0; i<gThreadCount; i++ )

??? {

??????? threadHandles[i] = CreateThread( NULL,?????????? // Security attributes

??????? ???????????????????????????????? 0,????????????? // Stack size

??????? ???????????????????????????????? threadFunction, // Thread function

??????? ??? ?????????????????????????????(LPVOID)i, // Data for thread func()

??????? ???????????????????????????????? 0,????????????? // Thread start mode

??????? ???????????????????????????????? NULL);????????? // Returned thread ID

??? }

?

??? WaitForMultipleObjects(gThreadCount, threadHandles, TRUE, INFINITE);

?

??? clock_t finish = clock();

??? printf("Executing time:%d\n", finish-start);

?

??? printf("global: %f\n", gSum / gIterations);

?

??? double sum = 0.0;

??? for(int i=0; i<gThreadCount; i++)

??????? sum += gPart[i];

??? printf("parts: %f\n", sum / gIterations);

?

??? return 0;

}

?

輸出信息:

Computing value of Pi:

Thread number:1: aaaaaaaaaaaa

Thread number:0: aaaaaaaaaaaa

Thread number:2: aaaaaaaaaaaa

part1 value:1.047198

Thread number:1: bbbbbbbbbbbb

part0 value:1.047198

Thread number:0: bbbbbbbbbbbb

part2 value:1.047198

Thread number:2: bbbbbbbbbbbb

Executing time:19109

global: 2.711738

parts: 3.141593

Press any key to continue

以上是輸出信息通過 gSum 求出來的值在 2.7 左右,事實上有的時候還會更低。 WHY ?問題出現在哪里呢?通過各個線程計算出來的值是對的,說明問題不是出現在這里,也就是說問題是出現在線程切換的時候使得 gSum 少加了一些值!什么時候切換會導致這個問題呢?問題出現在下面這一句里面:

??????? gSum += 4.0f / (1.0f + dx*dx);//cause problems here!

這一行等價于:

?????????????????? gSum = gSum + value;

這一行代碼相當于兩行代碼:

???????? temp = gSum + value;

???????? gSum = temp;

如果有兩個線程的話:

線程 A:

1、 ???????????? temp = gSum + value;

2、 ???????????? gSum = temp;

線程 B:

3、 ???????????? temp = gSum + value;

4、 ???????????? gSum = temp;

由于線程切換的任意性,這幾條指令的執行順序有以下幾種可能:

1 2 3 4 1 3 2 4 1 3 4 2 3 1 2 4 3 1 4 2 3 4 1 2

其中 1 3 2 4 順序就是會出錯的,很顯然按照 1 3 2 4 順序的時候 1 中的 value 就沒有被加進來了。這就是問題所在!同樣 1 3 4 2 3 1 2 4 3 1 4 2 都是有問題。

那如何解決這個問題呢?要把 1 2 捆綁在一起作為一個單位操作,即所謂原子操作,要么不執行,要么就全都執行了。

正確的代碼如下。給 gSum+= 操作放到一個 critical section 中,保證此時不會被線程切換干擾。關于 critical section 的詳細信息請參考 MSDN Good luck & have fun.

#include <windows.h>

#include <stdio.h>

?

const int gIterations = 100000;

const int gThreadCount = 4;

double gSum = 0.0;

CRITICAL_SECTION gCS;

?

DWORD WINAPI threadFunction(LPVOIDpArg)

{

???? double partialSum = 0.0;

?

???? for ( inti=(int)pArg+1; i<gIterations; i+=gThreadCount )

???? {

???????? double dx = (i - 0.5f) / gIterations;

???????? partialSum += 4.0f / (1.0f + dx*dx);

???? }

?

???? EnterCriticalSection(&gCS);

???? gSum += partialSum;

???? LeaveCriticalSection(&gCS);

?

???? return 0;

}

?

int main ()

{

???? printf("Computing value of Pi: \n");

?

???? InitializeCriticalSection(&gCS);

???? HANDLE threadHandles[gThreadCount];

???? for ( inti=0; i<gThreadCount; ++i )

???? {

???????? threadHandles[i] = CreateThread( NULL,?????????? // Security attributes

???????? ???????????????????????????????? 0,????????????? // Stack size

???????? ???????????????????????????????? threadFunction, // Thread function

???????? ???????????????????????????????? (LPVOID)i,????? // Data for thread func()

???????? ???????????????????????????????? 0,???????? ?????// Thread start mode

???????? ???????????????????????????????? NULL);????????? // Returned thread ID

???? }

???? WaitForMultipleObjects(gThreadCount, threadHandles,? TRUE, INFINITE);

???? DeleteCriticalSection(&gCS);

?

???? printf("%f\n", gSum / gIterations);

?

???? return 0;

}

?

Feedback

# re: 多線程計算PI碰到的問題  回復  更多評論   

2007-03-24 15:05 by 小熊
這應該算是由race condtion產生的問題吧?

# re: 多線程計算PI碰到的問題  回復  更多評論   

2007-03-26 21:14 by 小熊
上面對gSum += 4.0f / (1.0f + dx*dx);//cause problems here!
的分解有誤,正確應該由如下這些匯編代碼組成:

00401065 fmul qword ptr [dx]
00401068 fadd qword ptr [__real@3ff0000000000000 (403168h)]
0040106E fdivr qword ptr [__real@4010000000000000 (403160h)]
00401074 fadd qword ptr [gSum (4040A8h)]
0040107A fstp qword ptr [gSum (4040A8h)]

而gSum += i;則被翻譯成如下這些匯編代碼:

00401080 fild dword ptr [i]
00401083 fadd qword ptr [gSum (4040A8h)]
00401089 fstp qword ptr [gSum (4040A8h)]

# re: 多線程計算PI碰到的問題  回復  更多評論   

2007-03-30 15:27 by 小熊
printf("Hello Thread %d\n", num);
這一句被分解為以下匯編代碼

00401026 mov esi,esp
00401028 mov ecx,dword ptr [num]
0040102B push ecx
0040102C push offset MSVCR71D_NULL_THUNK_DATA+28h (4030CCh)
00401031 call dword ptr [__imp__printf (40309Ch)]
00401037 add esp,8
0040103A cmp esi,esp
0040103C call _RTC_CheckEsp (4011D0h)
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美黄色免费| 国产欧美一区二区精品性色| 欧美黑人国产人伦爽爽爽| 国产在线视频欧美| 久久亚洲精品网站| 亚洲国产精品成人va在线观看| 亚洲黄色性网站| 欧美午夜激情小视频| 亚洲一区二区在线播放| 久久综合九色综合久99| 亚洲精品五月天| 国产欧美一区视频| 免费影视亚洲| 午夜宅男欧美| 亚洲理论在线| 亚洲视频观看| 1024欧美极品| 国产欧美一区二区精品忘忧草| 久久久综合视频| 亚洲专区免费| 亚洲娇小video精品| 久久狠狠亚洲综合| 一区二区三区国产盗摄| 国内精品久久久久久久影视蜜臀 | 久久亚洲综合色| 性欧美办公室18xxxxhd| 亚洲精品日本| 亚洲国产精品电影在线观看| 永久免费精品影视网站| 国产日产高清欧美一区二区三区| 亚洲少妇一区| 亚洲一区二区av电影| 亚洲激情影视| 亚洲激情视频在线播放| 亚洲精品国久久99热| 国产色视频一区| 久久久久久久久蜜桃| 欧美极品一区| 久久视频在线看| 亚洲欧美激情精品一区二区| 亚洲日本中文字幕| 最新日韩精品| 亚洲第一福利视频| 99国产精品久久久| 亚洲女人天堂av| 免费日韩av| 欧美国产高清| 欧美精品91| 在线欧美三区| 亚洲女性喷水在线观看一区| 久久亚洲一区二区| 久久亚洲私人国产精品va媚药| 亚洲人被黑人高潮完整版| 久久国产色av| 国产精品v欧美精品v日本精品动漫 | 亚洲欧美在线免费| 欧美激情亚洲一区| 久久不射网站| 国产亚洲va综合人人澡精品| 一本色道久久加勒比精品| 久久久亚洲高清| 亚洲欧美另类在线| 欧美日韩午夜视频在线观看| 亚洲第一中文字幕在线观看| 久久国产主播| 中日韩男男gay无套| 欧美不卡一卡二卡免费版| 国产精品乱人伦一区二区| 一区二区三区欧美| 日韩亚洲在线观看| 欧美激情中文字幕一区二区| 伊人久久婷婷色综合98网| 欧美一区二区高清| 午夜在线a亚洲v天堂网2018| 国产精品久久久久久户外露出| 日韩视频在线一区二区| 久久久久亚洲综合| 99天天综合性| 欧美日韩国产精品一卡| 亚洲国产欧美日韩精品| 亚洲高清在线视频| 另类国产ts人妖高潮视频| 亚洲精品免费网站| 亚洲国产成人91精品| 国产精品a级| 欧美一区2区三区4区公司二百| 久久久久.com| 亚洲在线电影| 久久香蕉国产线看观看av| 最新国产乱人伦偷精品免费网站 | 亚洲电影免费观看高清完整版在线| 免费在线看一区| 亚洲欧美精品中文字幕在线| 国产一区二区三区av电影| 亚洲欧美日韩一区在线| 亚洲激情网址| 欧美一区二区三区四区在线观看 | 亚洲二区免费| 一区二区三区精品| 亚洲国产精品一区二区久| 99视频热这里只有精品免费| 亚洲电影免费观看高清| 欧美伊人精品成人久久综合97| 国产在线欧美| 欧美一区二区三区另类| 亚洲在线中文字幕| 欧美成人中文字幕在线| 久久九九有精品国产23| 欧美色123| 在线一区二区三区做爰视频网站| 一本色道久久| 激情文学综合丁香| 亚洲夜间福利| 亚洲一区二区免费| 欧美日本一区二区高清播放视频| 欧美aaaaaaaa牛牛影院| 亚洲激情视频在线播放| 免费视频亚洲| 亚洲激情视频网| 亚洲国产欧美另类丝袜| 性色av一区二区三区在线观看| 欧美在线播放高清精品| 国产午夜精品久久久| 亚洲欧美视频在线观看| 久久福利毛片| 欧美午夜视频在线| 亚洲欧美日韩直播| 久久永久免费| 亚洲精品视频免费观看| 欧美日韩精品在线观看| 日韩视频一区二区在线观看 | 欧美成人精品一区| 亚洲黄网站在线观看| 亚洲综合精品四区| 亚洲精品1234| 国产欧美一区二区视频| 久久艳片www.17c.com| 欧美69视频| 久久激情久久| 91久久精品国产91性色tv| 欧美日韩视频在线第一区| 久久精品免费电影| 香蕉精品999视频一区二区| 久久综合免费视频影院| 在线亚洲精品福利网址导航| 国产欧美一级| 国产精品久久999| 欧美日韩国产免费| 欧美中文在线免费| 亚洲少妇自拍| 99re热精品| 一区二区欧美在线| 亚洲国产精品久久久久婷婷老年| 久久精品中文字幕免费mv| 亚洲五月婷婷| 91久久极品少妇xxxxⅹ软件| 亚洲国产综合91精品麻豆| 国产女人精品视频| 国产揄拍国内精品对白| 国产视频欧美| 国产精品自在欧美一区| 欧美视频在线免费看| 国产精品扒开腿爽爽爽视频| 欧美性猛交xxxx乱大交退制版| 欧美激情第10页| 欧美一区二视频| 亚洲一区bb| 亚洲一区在线观看免费观看电影高清| 久热精品视频在线免费观看| 亚洲一区二区三区四区五区午夜| 亚洲欧洲另类| 亚洲午夜精品视频| 久久精品综合| 亚洲日韩欧美视频一区| 亚洲精品美女久久7777777| 日韩小视频在线观看专区| 最近中文字幕日韩精品| 欧美一二三区精品| 久久亚洲影院| 欧美日韩亚洲天堂| 国产欧美一区二区三区沐欲| 国产在线不卡视频| 99riav1国产精品视频| 欧美一区日韩一区| 欧美激情亚洲视频| 亚洲无人区一区| 欧美在线视频免费观看| 欧美激情亚洲自拍| 激情小说亚洲一区| 亚洲男人的天堂在线| 亚洲第一中文字幕在线观看| 亚洲无线观看| 欧美啪啪成人vr| 怡红院精品视频| av成人动漫| 亚洲国产一区二区a毛片| 欧美一区三区二区在线观看| 欧美日韩美女在线观看| 中日韩视频在线观看| 欧美~级网站不卡|