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

Kisser Leon

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

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

Posted on 2007-03-23 23:42 kk 閱讀(1970) 評(píng)論(3)  編輯 收藏 引用 所屬分類(lèi): 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 ,表示線程開(kāi)始執(zhí)行,輸出 Thread number:I bbbbbbb 則表示線程執(zhí)行完畢。有些地方還可以優(yōu)化的,不過(guò)這里只是為了演示多線程的問(wèn)題,所以就不予關(guān)注了。恩。

代碼如下。當(dāng)只有一個(gè) thread 的時(shí)候,結(jié)果是 OK 的( gSum==sum==3.14159* ,用等號(hào)有點(diǎn)問(wèn)題,但是結(jié)果差異在十萬(wàn)分之一以內(nèi))。當(dāng)有三個(gè) threads 的時(shí)候,問(wèn)題就開(kāi)始出現(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

以上是輸出信息通過(guò) gSum 求出來(lái)的值在 2.7 左右,事實(shí)上有的時(shí)候還會(huì)更低。 WHY ?問(wèn)題出現(xiàn)在哪里呢?通過(guò)各個(gè)線程計(jì)算出來(lái)的值是對(duì)的,說(shuō)明問(wèn)題不是出現(xiàn)在這里,也就是說(shuō)問(wèn)題是出現(xiàn)在線程切換的時(shí)候使得 gSum 少加了一些值!什么時(shí)候切換會(huì)導(dǎo)致這個(gè)問(wèn)題呢?問(wèn)題出現(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 就沒(méi)有被加進(jìn)來(lái)了。這就是問(wèn)題所在!同樣 1 3 4 2 3 1 2 4 3 1 4 2 都是有問(wèn)題。

那如何解決這個(gè)問(wèn)題呢?要把 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碰到的問(wèn)題  回復(fù)  更多評(píng)論   

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

# re: 多線程計(jì)算PI碰到的問(wèn)題  回復(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碰到的問(wèn)題  回復(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>
            国产一区二区三区丝袜| 亚洲激情综合| 国产亚洲欧洲一区高清在线观看 | 国产精品网站视频| 国产精品久久久久久一区二区三区| 欧美视频网站| 国产精品久久一区二区三区| 国产精品一区二区久久久| 国产麻豆精品视频| 国内综合精品午夜久久资源| 一色屋精品视频在线观看网站| 樱桃国产成人精品视频| 91久久午夜| 一区二区三区视频观看| 亚洲综合欧美| 欧美主播一区二区三区| 老巨人导航500精品| 欧美高清不卡在线| 日韩亚洲国产欧美| 午夜精品久久久久影视 | 欧美成人久久| 欧美日韩在线免费观看| 国产麻豆9l精品三级站| 精品动漫3d一区二区三区免费 | 欧美在线免费观看亚洲| 久久蜜臀精品av| 欧美电影在线播放| 国产精品成人免费视频| 国产一级揄自揄精品视频| 怡红院av一区二区三区| 99精品视频免费| 香蕉视频成人在线观看| 老司机午夜精品视频| 亚洲激情网站免费观看| 亚洲午夜高清视频| 久久久久女教师免费一区| 欧美日韩国产黄| 国产欧美精品一区二区色综合 | 欧美成人精品不卡视频在线观看 | 国产一区在线观看视频| 亚洲精品国产视频| 欧美一级淫片aaaaaaa视频| 老牛嫩草一区二区三区日本| 91久久中文| 欧美在线免费观看| 欧美精品一区二区三区四区| 国产精品男人爽免费视频1| 影音先锋国产精品| 亚洲午夜未删减在线观看| 久久亚洲一区二区| 这里只有精品视频| 久久综合色天天久久综合图片| 欧美视频一区二区三区四区| 一区一区视频| 欧美一级电影久久| 亚洲日韩中文字幕在线播放| 欧美在线日韩| 国产精品v欧美精品v日韩| 亚洲国产成人在线播放| 午夜一级久久| 亚洲人成人一区二区三区| 久久成年人视频| 国产精品草莓在线免费观看| 亚洲激情国产| 久久精品天堂| 亚洲一区二区三区中文字幕在线| 欧美成人按摩| 在线看成人片| 久久精品国产99国产精品澳门| 亚洲三级影院| 蜜桃久久精品一区二区| 精品999网站| 久久激情五月丁香伊人| 在线综合+亚洲+欧美中文字幕| 欧美大片免费观看在线观看网站推荐| 国产一区二区毛片| 欧美亚洲日本一区| 亚洲最新视频在线| 欧美精品1区2区| 亚洲国产精品123| 久久一二三区| 性色av一区二区三区| 国产精品自拍在线| 午夜国产一区| 亚洲伊人色欲综合网| 欧美色大人视频| 在线一区二区日韩| 亚洲人成毛片在线播放| 欧美va亚洲va香蕉在线| 亚洲欧洲日本mm| 欧美大片一区二区三区| 久久久91精品国产一区二区三区 | 国产精品日韩在线一区| 中文精品视频| 一区二区三区国产盗摄| 国产精品xxx在线观看www| 宅男噜噜噜66一区二区66| 亚洲精品看片| 欧美日韩国产在线一区| 亚洲最新在线| 日韩一区二区精品| 欧美日韩情趣电影| 亚洲欧美999| 亚洲欧美清纯在线制服| 国产视频在线观看一区二区三区| 欧美与黑人午夜性猛交久久久| 午夜性色一区二区三区免费视频| 国产欧美一区二区色老头| 欧美在现视频| 久久九九全国免费精品观看| 亚洲成色www8888| 欧美激情第二页| 欧美日本一区二区视频在线观看| 亚洲一区二区三区四区中文| 亚洲一区二区三区乱码aⅴ蜜桃女| 国产精品久久久久免费a∨| 久久狠狠亚洲综合| 久久久久久免费| 亚洲人成欧美中文字幕| 99riav1国产精品视频| 国产精品久久久99| 久久精品视频一| 久久亚洲不卡| 一本色道久久| 亚洲综合色激情五月| 精品99一区二区三区| 亚洲高清视频一区| 欧美色视频日本高清在线观看| 欧美一区二区在线看| 久久免费精品视频| 夜夜精品视频| 性欧美xxxx大乳国产app| 亚洲国产精品ⅴa在线观看| 亚洲精品日韩久久| 国产亚洲观看| 最新热久久免费视频| 国产精品女人毛片| 欧美h视频在线| 欧美日韩在线影院| 久久婷婷亚洲| 欧美日韩高清区| 久久久www| 欧美日本一区二区高清播放视频| 欧美亚洲一区在线| 欧美成人精精品一区二区频| 先锋影音久久久| 免费观看成人鲁鲁鲁鲁鲁视频| 亚洲专区免费| 免费试看一区| 久久精品国产91精品亚洲| 欧美精品亚洲二区| 久久久久久综合网天天| 欧美美女bbbb| 久久久免费av| 国产精品成人av性教育| 奶水喷射视频一区| 国产精品亚发布| 亚洲黄色av| 伊人久久久大香线蕉综合直播| av成人老司机| 亚洲精品国产精品乱码不99| 午夜精品国产| 亚洲视频一区在线| 免费观看亚洲视频大全| 久久激情网站| 欧美手机在线视频| 欧美国产精品中文字幕| 国产一区二区高清视频| 一本久久综合亚洲鲁鲁| 亚洲人久久久| 久久人人97超碰国产公开结果| 午夜精品电影| 欧美三区在线| 亚洲区第一页| 91久久久久久久久| 久久视频在线免费观看| 欧美在线观看一二区| 欧美日韩在线观看一区二区| 欧美激情一区在线| 在线电影一区| 欧美一区二区三区四区高清| 亚洲一区二区伦理| 欧美精品在线视频| 欧美国产免费| 亚洲国产va精品久久久不卡综合| 性欧美大战久久久久久久免费观看| 亚洲网站视频| 欧美日韩不卡| 亚洲三级色网| 亚洲狼人精品一区二区三区| 老鸭窝91久久精品色噜噜导演| 久久精品久久99精品久久| 国产麻豆综合| 亚洲欧美日韩精品久久久| 亚洲性视频网址| 欧美日韩综合一区| 一本色道久久加勒比88综合| 正在播放亚洲一区| 欧美色网一区二区| 亚洲视频免费看|