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

Kisser Leon

這個(gè)kisser不太冷
posts - 100, comments - 102, trackbacks - 0, articles - 0

多線程計(jì)算PI碰到的問題

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

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

代碼如下。當(dāng)只有一個(gè) thread 的時(shí)候,結(jié)果是 OK 的( gSum==sum==3.14159* ,用等號(hào)有點(diǎn)問題,但是結(jié)果差異在十萬(wàn)分之一以內(nèi))。當(dāng)有三個(gè) threads 的時(shí)候,問題就開始出現(xiàn)了! gSum 計(jì)算出來(lái)只有 2.* !怎么會(huì)這樣子呢?各位有興趣的話,可以運(yùn)行下面的代碼試試看。接著看下面的分析。

#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 求出來(lái)的值在 2.7 左右,事實(shí)上有的時(shí)候還會(huì)更低。 WHY ?問題出現(xiàn)在哪里呢?通過各個(gè)線程計(jì)算出來(lái)的值是對(duì)的,說(shuō)明問題不是出現(xiàn)在這里,也就是說(shuō)問題是出現(xiàn)在線程切換的時(shí)候使得 gSum 少加了一些值!什么時(shí)候切換會(huì)導(dǎo)致這個(gè)問題呢?問題出現(xiàn)在下面這一句里面:

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

這一行等價(jià)于:

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

這一行代碼相當(dāng)于兩行代碼:

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

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

如果有兩個(gè)線程的話:

線程 A:

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

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

線程 B:

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

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

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

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 順序就是會(huì)出錯(cuò)的,很顯然按照 1 3 2 4 順序的時(shí)候 1 中的 value 就沒有被加進(jìn)來(lái)了。這就是問題所在!同樣 1 3 4 2 3 1 2 4 3 1 4 2 都是有問題。

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

正確的代碼如下。給 gSum+= 操作放到一個(gè) critical section 中,保證此時(shí)不會(huì)被線程切換干擾。關(guān)于 critical section 的詳細(xì)信息請(qǐng)參考 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: 多線程計(jì)算PI碰到的問題  回復(fù)  更多評(píng)論   

2007-03-24 15:05 by 小熊
這應(yīng)該算是由race condtion產(chǎn)生的問題吧?

# re: 多線程計(jì)算PI碰到的問題  回復(fù)  更多評(píng)論   

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

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: 多線程計(jì)算PI碰到的問題  回復(fù)  更多評(píng)論   

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>
            午夜精品免费在线| 亚洲国产成人在线播放| 亚洲一区三区视频在线观看| 99天天综合性| 欧美精品久久99| 亚洲美女在线国产| 亚洲专区一区| 亚洲国产精品一区二区第四页av| 亚洲大胆av| 欧美电影免费观看高清完整版| 欧美激情久久久| 一区二区三区高清不卡| 国产精品夫妻自拍| 性做久久久久久久久| 免费久久99精品国产自| 日韩小视频在线观看专区| 国产精品日韩精品欧美精品| 欧美一区二区三区电影在线观看| 欧美成人综合网站| 在线视频欧美日韩精品| 国产精品久久久| 久久精品国产亚洲精品| 欧美福利专区| 欧美一级在线亚洲天堂| **欧美日韩vr在线| 国产精品久久久久一区二区三区共| 欧美亚洲视频一区二区| 亚洲国产精品va在看黑人| 欧美在线免费观看亚洲| 亚洲精品社区| 国产在线精品成人一区二区三区 | 午夜精彩视频在线观看不卡| 国产亚洲一区在线播放| 欧美日韩国产二区| 久久综合久久综合九色| 午夜国产精品视频| 亚洲美女在线视频| 亚洲国产精品视频一区| 久久视频在线看| 亚洲欧美日产图| 中文av一区二区| 亚洲欧洲日夜超级视频| 国产私拍一区| 国产伦精品一区二区三区四区免费 | 欧美一区二区三区婷婷月色| 亚洲国产日韩美| 久久久久久久一区二区| 午夜精品久久久久久| 一本色道久久综合| 亚洲全部视频| 亚洲国产成人久久综合一区| 激情国产一区| 国模吧视频一区| 国产手机视频一区二区| 国产精品一区二区你懂得 | 欧美日韩三级电影在线| 欧美mv日韩mv国产网站| 久久久人成影片一区二区三区观看| 亚洲男人影院| 午夜国产精品视频免费体验区| 久久免费精品日本久久中文字幕| 亚洲免费影院| 日韩特黄影片| 国产一区二区欧美日韩| 欧美紧缚bdsm在线视频| 中国av一区| 亚洲国产美女久久久久| 亚洲免费观看视频| 一本大道av伊人久久综合| 激情av一区| 一区二区欧美精品| 国产精品99久久久久久宅男| 日韩一区二区精品| 亚洲午夜在线观看| 亚洲——在线| 久久久国产一区二区| 免费在线观看一区二区| 久热精品视频在线| 欧美国产日韩一区二区| 欧美日韩国产大片| 国产欧美精品| 在线观看成人小视频| 亚洲日本激情| 亚洲欧美另类中文字幕| 久久久久国产精品人| 亚洲国产精品毛片| 制服丝袜亚洲播放| 久久精品一区二区三区不卡牛牛| 久久女同互慰一区二区三区| 欧美精品一区二区三区在线播放 | 亚洲三级网站| 亚洲欧美中日韩| 老司机67194精品线观看| 亚洲免费大片| 久久久午夜精品| 欧美视频在线观看一区二区| 国产一区日韩欧美| 亚洲日本va午夜在线影院| 亚洲欧美日韩国产成人| 欧美黄色一区二区| 亚洲欧美视频一区| 欧美激情国产日韩| 狠狠88综合久久久久综合网| 中文国产成人精品久久一| 久久一区中文字幕| 亚洲资源在线观看| 亚洲精品亚洲人成人网| 欧美成人三级在线| 亚洲精品视频免费观看| 久久久水蜜桃av免费网站| 欧美手机在线视频| 亚洲激情网址| 久久久久久久久久久一区| 妖精视频成人观看www| 翔田千里一区二区| 久久久久一区二区三区四区| 中国女人久久久| 欧美va天堂| 伊人一区二区三区久久精品| 欧美亚洲专区| 亚洲宅男天堂在线观看无病毒| 欧美成在线视频| 亚洲盗摄视频| 老鸭窝亚洲一区二区三区| 亚洲特级毛片| 国产精品超碰97尤物18| 一区二区三区三区在线| 91久久精品国产91久久性色| 久久女同互慰一区二区三区| 娇妻被交换粗又大又硬视频欧美| 欧美在线3区| 亚洲永久网站| 国产欧美精品在线| 久久成人亚洲| 亚洲欧美在线观看| 国产一区二区中文| 久久综合色一综合色88| 久久久久欧美精品| 激情校园亚洲| 亚洲国产日韩在线一区模特| 欧美精品久久久久久久免费观看| 亚洲理伦在线| 亚洲天堂激情| 国模吧视频一区| 久久久久欧美| 蜜桃精品久久久久久久免费影院| 亚洲国产美女精品久久久久∴| 欧美高清视频一区二区三区在线观看| 久久蜜桃精品| 日韩一级大片| 亚洲午夜视频| 狠狠色狠狠色综合日日91app| 久久综合九色欧美综合狠狠| 久久人人爽人人| 99国产精品国产精品久久| 99精品视频一区二区三区| 国产精品一区二区久久久久 | 亚洲第一主播视频| 欧美精品日韩| 欧美一级理论片| 欧美亚洲自偷自偷| 亚洲二区视频在线| 91久久精品国产91久久| 国产精品美女一区二区| 免费观看一区| 国产精品海角社区在线观看| 久久精品国内一区二区三区| 欧美一级黄色网| 久久9热精品视频| 国产精品亚洲综合一区在线观看| 午夜综合激情| 久久久久久网| 亚洲淫性视频| 久久久久成人精品| 亚洲黄一区二区三区| 亚洲一区中文字幕在线观看| 亚洲黄色精品| 午夜视频一区二区| 亚洲精品久久久久久久久| 亚洲视频播放| 亚洲激情网站免费观看| 亚洲一区视频在线| 亚洲精品偷拍| 久久精品国产久精国产思思| 一本色道88久久加勒比精品| 久久国产精彩视频| 亚洲自拍电影| 欧美激情在线狂野欧美精品| 久久久999精品免费| 欧美日韩一区二区三区在线视频| 欧美成人a视频| 国产三级精品三级| 亚洲欧洲日产国产网站| 在线不卡中文字幕| 先锋亚洲精品| 性娇小13――14欧美| 欧美日韩精品免费观看视频| 亚洲高清不卡| 亚洲国产成人久久综合一区| 久久精品人人做人人综合|