±à¼ÍƼö: |
±¾ÎÄÀ´×ÔÓÚcsdn£¬OpenMP±à³ÌÄ£ÐÍÒÔÏß³ÌΪ»ù´¡£¬Í¨¹ý±àÒëÖÆµ¼Ö¸ÁîÖÆµ¼²¢Ðл¯£¬ÓÐÈýÖÖ±à³ÌÒªËØ¿ÉÒÔʵÏÖ²¢Ðл¯¿ØÖÆ. |
|
1.OpenMP»ù±¾¸ÅÄî
OpenMPÊÇÒ»ÖÖÓÃÓÚ¹²ÏíÄÚ´æ²¢ÐÐϵͳµÄ¶àÏ̳߳ÌÐòÉè¼Æ·½°¸£¬Ö§³ÖµÄ±à³ÌÓïÑÔ°üÀ¨C¡¢C++ºÍFortran¡£OpenMPÌṩÁ˶Բ¢ÐÐËã·¨µÄ¸ß²ã³éÏóÃèÊö£¬ÌرðÊʺÏÔÚ¶àºËCPU»úÆ÷ÉϵIJ¢ÐгÌÐòÉè¼Æ¡£±àÒëÆ÷¸ù¾Ý³ÌÐòÖÐÌí¼ÓµÄpragmaÖ¸Á×Ô¶¯½«³ÌÐò²¢Ðд¦Àí£¬Ê¹ÓÃOpenMP½µµÍÁ˲¢Ðбà³ÌµÄÄѶȺ͸´ÔÓ¶È¡£µ±±àÒëÆ÷²»Ö§³ÖOpenMPʱ£¬³ÌÐò»áÍË»¯³ÉÆÕͨ£¨´®ÐУ©³ÌÐò¡£³ÌÐòÖÐÒÑÓеÄOpenMPÖ¸Áî²»»áÓ°Ïì³ÌÐòµÄÕý³£±àÒëÔËÐС£ÔÚVSÖÐÆôÓÃOpenMPºÜ¼òµ¥£¬ºÜ¶àÖ÷Á÷µÄ±àÒë»·¾³¶¼ÄÚÖÃÁËOpenMP¡£ÔÚÏîÄ¿ÉÏÓÒ¼ü->ÊôÐÔ->ÅäÖÃÊôÐÔ->C/C++->ÓïÑÔ->OpenMPÖ§³Ö£¬Ñ¡Ôñ¡°ÊÇ¡±¼´¿É¡£
2.OpenMPÖ´ÐÐģʽ
OpenMP²ÉÓÃfork-joinµÄÖ´ÐÐģʽ¡£¿ªÊ¼µÄʱºòÖ»´æÔÚÒ»¸öÖ÷Ị̈߳¬µ±ÐèÒª½øÐв¢ÐмÆËãµÄʱºò£¬ÅÉÉú³öÈô¸É¸ö·ÖÖ§Ïß³ÌÀ´Ö´Ðв¢ÐÐÈÎÎñ¡£µ±²¢ÐдúÂëÖ´ÐÐÍê³ÉÖ®ºó£¬·ÖÖ§Ï̻߳áºÏ£¬²¢°Ñ¿ØÖÆÁ÷³Ì½»¸øµ¥¶ÀµÄÖ÷Ï̡߳£
Ò»¸öµäÐ͵Äfork-joinÖ´ÐÐÄ£Ð͵ÄʾÒâͼÈçÏ£º

OpenMP±à³ÌÄ£ÐÍÒÔÏß³ÌΪ»ù´¡£¬Í¨¹ý±àÒëÖÆµ¼Ö¸ÁîÖÆµ¼²¢Ðл¯£¬ÓÐÈýÖÖ±à³ÌÒªËØ¿ÉÒÔʵÏÖ²¢Ðл¯¿ØÖÆ£¬ËûÃÇ·Ö±ðÊDZàÒëÖÆµ¼¡¢APIº¯Êý¼¯ºÍ»·¾³±äÁ¿¡£
3.±àÒëÆ÷Ö¸Áî
OpenMPµÄ±àÒëÆ÷Ö¸ÁîµÄÄ¿±êÖ÷ÒªÓУº
1£©²úÉúÒ»¸ö²¢ÐÐÇøÓò£»
2£©»®·ÖÏß³ÌÖеĴúÂë¿é£»
3£©ÔÚÏß³ÌÖ®¼ä·ÖÅäÑ»·µü´ú£»
4£©ÐòÁл¯´úÂë¶Î£»
5£©Í¬²½Ï̼߳äµÄ¹¤×÷¡£±àÒëÖÆµ¼Ö¸ÁîÒÔ#pragma omp ¿ªÊ¼£¬ºó±ß¸ú¾ßÌåµÄ¹¦ÄÜÖ¸Á¸ñʽÈ磺#pragma
omp Ö¸Áî[×Ó¾ä],[×Ó¾ä]¡]¡£
³£ÓõŦÄÜÖ¸ÁîÈçÏ£º
parallel £ºÓÃÔÚÒ»¸ö½á¹¹¿é֮ǰ£¬±íʾÕâ¶Î´úÂ뽫±»¶à¸öÏ̲߳¢ÐÐÖ´ÐУ»
for£ºÓÃÓÚforÑ»·Óï¾ä֮ǰ£¬±íʾ½«Ñ»·¼ÆËãÈÎÎñ·ÖÅäµ½¶à¸öÏß³ÌÖв¢ÐÐÖ´ÐУ¬ÒÔʵÏÖÈÎÎñ·Öµ££¬±ØÐëÓɱà³ÌÈËÔ±×Ô¼º±£Ö¤Ã¿´ÎÑ»·Ö®¼äÎÞÊý¾ÝÏà¹ØÐÔ£»
parallel for £ºparallelºÍforÖ¸ÁîµÄ½áºÏ£¬Ò²ÊÇÓÃÔÚforÑ»·Óï¾ä֮ǰ£¬±íʾforÑ»·ÌåµÄ´úÂ뽫±»¶à¸öÏ̲߳¢ÐÐÖ´ÐУ¬Ëüͬʱ¾ßÓв¢ÐÐÓòµÄ²úÉúºÍÈÎÎñ·Öµ£Á½¸ö¹¦ÄÜ£»
sections £ºÓÃÔڿɱ»²¢ÐÐÖ´ÐеĴúÂë¶Î֮ǰ£¬ÓÃÓÚʵÏÖ¶à¸ö½á¹¹¿éÓï¾äµÄÈÎÎñ·Öµ££¬¿É²¢ÐÐÖ´ÐеĴúÂë¶Î¸÷×ÔÓÃsectionÖ¸Áî±ê³ö£¨×¢ÒâÇø·ÖsectionsºÍsection£©£»
parallel sections£ºparallelºÍsectionsÁ½¸öÓï¾äµÄ½áºÏ£¬ÀàËÆÓÚparallel?for£»
single£ºÓÃÔÚ²¢ÐÐÓòÄÚ£¬±íʾһ¶ÎÖ»±»µ¥¸öÏß³ÌÖ´ÐеĴúÂ룻
critical£ºÓÃÔÚÒ»¶Î´úÂëÁÙ½çÇøÖ®Ç°£¬±£Ö¤Ã¿´ÎÖ»ÓÐÒ»¸öOpenMPÏ߳̽øÈ룻
flush£º±£Ö¤¸÷¸öOpenMPÏ̵߳ÄÊý¾ÝÓ°ÏñµÄÒ»ÖÂÐÔ£»
barrier£ºÓÃÓÚ²¢ÐÐÓòÄÚ´úÂëµÄÏß³Ìͬ²½£¬Ïß³ÌÖ´Ðе½barrierʱҪͣϵȴý£¬Ö±µ½ËùÓÐÏ̶߳¼Ö´Ðе½barrierʱ²Å¼ÌÐøÍùÏÂÖ´ÐУ»
atomic£ºÓÃÓÚÖ¸¶¨Ò»¸öÊý¾Ý²Ù×÷ÐèÒªÔ×ÓÐÔµØÍê³É£»
master£ºÓÃÓÚÖ¸¶¨Ò»¶Î´úÂëÓÉÖ÷Ïß³ÌÖ´ÐУ»
threadprivate£ºÓÃÓÚÖ¸¶¨Ò»¸ö»ò¶à¸ö±äÁ¿ÊÇÏß³ÌרÓ㬺óÃæ»á½âÊÍÏß³ÌרÓкÍ˽ÓеÄÇø±ð¡£
ÏàÓ¦µÄOpenMP×Ó¾äΪ£º
private£ºÖ¸¶¨Ò»¸ö»ò¶à¸ö±äÁ¿ÔÚÿ¸öÏß³ÌÖж¼ÓÐËü×Ô¼ºµÄ˽Óи±±¾£»
firstprivate£ºÖ¸¶¨Ò»¸ö»ò¶à¸ö±äÁ¿ÔÚÿ¸öÏ̶߳¼ÓÐËü×Ô¼ºµÄ˽Óи±±¾£¬²¢ÇÒ˽ÓбäÁ¿ÒªÔÚ½øÈë²¢ÐÐÓò»òÈÎÎñ·Öµ£Óòʱ£¬¼Ì³ÐÖ÷Ïß³ÌÖеÄͬÃû±äÁ¿µÄÖµ×÷Ϊ³õÖµ£»
lastprivate£ºÊÇÓÃÀ´Ö¸¶¨½«Ïß³ÌÖеÄÒ»¸ö»ò¶à¸ö˽ÓбäÁ¿µÄÖµÔÚ²¢Ðд¦Àí½áÊøºó¸´ÖƵ½Ö÷Ïß³ÌÖеÄͬÃû±äÁ¿ÖУ¬¸ºÔ𿽱´µÄÏß³ÌÊÇfor»òsectionsÈÎÎñ·Öµ£ÖеÄ×îºóÒ»¸öỊ̈߳»
reduction£ºÓÃÀ´Ö¸¶¨Ò»¸ö»ò¶à¸ö±äÁ¿ÊÇ˽Óе쬲¢ÇÒÔÚ²¢Ðд¦Àí½áÊøºóÕâЩ±äÁ¿ÒªÖ´ÐÐÖ¸¶¨µÄ¹éÔ¼ÔËË㣬²¢½«½á¹û·µ»Ø¸øÖ÷Ïß³ÌͬÃû±äÁ¿£»
nowait£ºÖ¸³ö²¢·¢Ï߳̿ÉÒÔºöÂÔÆäËûÖÆµ¼Ö¸Áî°µº¬µÄ·ÕÏͬ²½£»
num_threads£ºÖ¸¶¨²¢ÐÐÓòÄÚµÄÏ̵߳ÄÊýÄ¿£»
schedule£ºÖ¸¶¨forÈÎÎñ·Öµ£ÖеÄÈÎÎñ·ÖÅäµ÷¶ÈÀàÐÍ£»
shared£ºÖ¸¶¨Ò»¸ö»ò¶à¸ö±äÁ¿Îª¶à¸öÏ̼߳äµÄ¹²Ïí±äÁ¿£»
ordered£ºÓÃÀ´Ö¸¶¨forÈÎÎñ·Öµ£ÓòÄÚÖ¸¶¨´úÂë¶ÎÐèÒª°´ÕÕ´®ÐÐÑ»·´ÎÐòÖ´ÐУ»
copyprivate£ºÅäºÏsingleÖ¸Á½«Ö¸¶¨Ï̵߳ÄרÓбäÁ¿¹ã²¥µ½²¢ÐÐÓòÄÚÆäËûÏ̵߳ÄͬÃû±äÁ¿ÖУ»
copyin n£ºÓÃÀ´Ö¸¶¨Ò»¸öthreadprivateÀàÐ͵ıäÁ¿ÐèÒªÓÃÖ÷Ïß³ÌͬÃû±äÁ¿½øÐгõʼ»¯£»
default£ºÓÃÀ´Ö¸¶¨²¢ÐÐÓòÄڵıäÁ¿µÄʹÓ÷½Ê½£¬È±Ê¡ÊÇshared¡£
4.APIº¯Êý
³ýÉÏÊö±àÒëÖÆµ¼Ö¸ÁîÖ®Í⣬OpenMP»¹ÌṩÁËÒ»×éAPIº¯ÊýÓÃÓÚ¿ØÖƲ¢·¢Ï̵߳ÄijЩÐÐΪ£¬ÏÂÃæÊÇһЩ³£ÓõÄOpenMP
APIº¯ÊýÒÔ¼°ËµÃ÷£º

5.»·¾³±äÁ¿
OpenMPÌṩÁËһЩ»·¾³±äÁ¿£¬ÓÃÀ´ÔÚÔËÐÐʱ¶Ô²¢ÐдúÂëµÄÖ´ÐнøÐпØÖÆ¡£ÕâЩ»·¾³±äÁ¿¿ÉÒÔ¿ØÖÆ£º1£©ÉèÖÃÏß³ÌÊý£»2£©Ö¸¶¨Ñ»·ÈçºÎ»®·Ö£»3£©½«Ḭ̈߳󶨵½´¦ÀíÆ÷£»4£©ÆôÓÃ/½ûÓÃǶÌײ¢ÐУ¬ÉèÖÃ×î´óµÄǶÌײ¢Ðм¶±ð£»5£©ÆôÓÃ/½ûÓö¯Ì¬Ị̈߳»6£©ÉèÖÃÏ̶߳ÑÕ»´óС£»7£©ÉèÖÃÏ̵߳ȴý²ßÂÔ¡£³£ÓõĻ·¾³±äÁ¿£º
OMP_SCHEDULE£ºÓÃÓÚforÑ»·²¢Ðл¯ºóµÄµ÷¶È£¬ËüµÄÖµ¾ÍÊÇÑ»·µ÷¶ÈµÄÀàÐÍ£»
OMP_NUM_THREADS£ºÓÃÓÚÉèÖò¢ÐÐÓòÖеÄÏß³ÌÊý£»
OMP_DYNAMIC£ºÍ¨¹ýÉ趨±äÁ¿Öµ£¬À´È·¶¨ÊÇ·ñÔÊÐí¶¯Ì¬É趨²¢ÐÐÓòÄÚµÄÏß³ÌÊý£»
OMP_NESTED£ºÖ¸³öÊÇ·ñ¿ÉÒÔ²¢ÐÐǶÌס£
(1).OpenMPÖ¸Áî¼°×Ó¾äÓ÷¨
(2).parallel
parallel ÊÇÓÃÀ´¹¹ÔìÒ»¸ö²¢ÐпéµÄ£¬Ò²¿ÉÒÔʹÓÃÆäËûÖ¸ÁîÈçfor¡¢sectionsµÈºÍËüÅäºÏʹÓá£parallelÖ¸ÁîÊÇÓÃÀ´ÎªÒ»¶Î´úÂë´´½¨¶à¸öÏß³ÌÀ´Ö´ÐÐËüµÄ¡£parallel¿éÖеÄÿÐдúÂë¶¼±»¶à¸öÏß³ÌÖØ¸´Ö´ÐС£ºÍ´«Í³µÄ´´½¨Ï̺߳¯Êý±ÈÆðÀ´£¬Ï൱ÓÚΪһ¸öÏß³ÌÈë¿Úº¯ÊýÖØ¸´µ÷Óô´½¨Ï̺߳¯ÊýÀ´´´½¨Ï̲߳¢µÈ´ýÏß³ÌÖ´ÐÐÍê¡£³ÌÐòʾÀýÈçÏ£º
void fun1()
{
#pragma omp parallel num_threads(6) //¶¨Òå6¸öỊ̈߳¬Ã¿¸öÏ̶߳¼½«ÔËÐÐ{}ÄÚ´úÂ룬ÔËÐнá¹û£ºÊä³ö6´ÎTest
{
cout << "Test" << endl;
}
system("pause");
}
|
(3)for
forÖ¸ÁîÔòÊÇÓÃÀ´½«Ò»¸öforÑ»··ÖÅäµ½¶à¸öÏß³ÌÖÐÖ´ÐС£forÖ¸ÁîÒ»°ã¿ÉÒÔºÍparallelÖ¸ÁîºÏÆðÀ´ÐγÉparallel
forÖ¸ÁîʹÓã¬Ò²¿ÉÒÔµ¥¶ÀÓÃÔÚparallelÓï¾äµÄ²¢ÐпéÖС£parallel forÓÃÓÚÉú³ÉÒ»¸ö²¢ÐÐÓò£¬²¢½«¼ÆËãÈÎÎñÔÚ¶à¸öÏß³ÌÖ®¼ä·ÖÅ䣬ÓÃÓÚ·Öµ£ÈÎÎñ¡£³ÌÐòʾÀýÈçÏ£º
void fun2()
{
#pragma omp parallel for num_threads(6) {
printf("OpenMP Test, Ï̱߳àºÅΪ: %d\n", omp_get_thread_num());
} //Ö¸¶¨ÁË6¸öỊ̈߳¬µü´úÁ¿Îª12£¬Ã¿¸öÏ̶߳¼·Öµ½ÁË12/6=2´ÎµÄµü´úÁ¿¡£
system("pause");
}
|
(4)sections & section
sectionÓï¾äÊÇÓÃÔÚsectionsÓï¾äÀïÓÃÀ´½«sectionsÓï¾äÀïµÄ´úÂë»®·Ö³É¼¸¸ö²»Í¬µÄ¶Î£¬Ã¿¶Î¶¼²¢ÐÐÖ´ÐС£Óï·¨¸ñʽÈçÏ£º
#pragma omp [parallel]
sections [×Ó¾ä]
{
#pragma omp section
{
´úÂë¿é
}
#pragma omp section
{
´úÂë¿é
}
}
|
˵Ã÷¸÷¸ösectionÀïµÄ´úÂë¶¼ÊDz¢ÐÐÖ´Ðе쬲¢ÇÒ¸÷¸ösection±»·ÖÅäµ½²»Í¬µÄÏß³ÌÖ´ÐС£
ʹÓÃsectionÓï¾äʱ£¬ÐèҪעÒâµÄÊÇÕâÖÖ·½Ê½ÐèÒª±£Ö¤¸÷¸ösectionÀïµÄ´úÂëÖ´ÐÐʱ¼äÏà²î²»´ó£¬·ñÔòij¸ösectionÖ´ÐÐʱ¼ä±ÈÆäËûsection¹ý³¤¾Í´ï²»µ½²¢ÐÐÖ´ÐеÄЧ¹ûÁË¡£ÓÃforÓï¾äÀ´·Ö̯ÊÇÓÉϵͳ×Ô¶¯½øÐУ¬Ö»ÒªÃ¿´ÎÑ»·¼äûÓÐʱ¼äÉϵIJî¾à£¬ÄÇô·Ö̯ÊǺܾùÔȵģ¬Ê¹ÓÃsectionÀ´»®·ÖÏß³ÌÊÇÒ»ÖÖÊÖ¹¤»®·ÖÏ̵߳ķ½Ê½¡£
(5) private
private×Ó¾äÓÃÓÚ½«Ò»¸ö»ò¶à¸ö±äÁ¿ÉùÃ÷³ÉÏß³Ì˽ÓеıäÁ¿£¬±äÁ¿ÉùÃ÷³É˽ÓбäÁ¿ºó£¬Ö¸¶¨Ã¿¸öÏ̶߳¼ÓÐËü×Ô¼ºµÄ±äÁ¿Ë½Óи±±¾£¬ÆäËûÏß³ÌÎÞ·¨·ÃÎÊ˽Óи±±¾¡£¼´Ê¹ÔÚ²¢ÐÐÇøÓòÍâÓÐͬÃûµÄ¹²Ïí±äÁ¿£¬¹²Ïí±äÁ¿ÔÚ²¢ÐÐÇøÓòÄÚ²»ÆðÈκÎ×÷Ó㬲¢ÇÒ²¢ÐÐÇøÓòÄÚ²»»á²Ù×÷µ½ÍâÃæµÄ¹²Ïí±äÁ¿¡£³ÌÐòʾÀýÈçÏ£º
int k = 100;
#pragma omp parallel for private(k)
for( k=0; k < 3; k++)
{
printf("k=%d/n", k);
}
printf("last k=%d/n", k);
|
ÉÏÃæ³ÌÐòÖ´Ðкó´òÓ¡µÄ½á¹ûÈçÏ£º
k=0
k=1
k=2
k=3
last k=100 |
´Ó´òÓ¡½á¹û¿ÉÒÔ¿´³ö£¬forÑ»·Ç°µÄ±äÁ¿kºÍÑ»·ÇøÓòÄڵıäÁ¿kÆäʵÊÇÁ½¸ö²»Í¬µÄ±äÁ¿¡£ÓÃprivate×Ó¾äÉùÃ÷µÄ˽ÓбäÁ¿µÄ³õʼֵÔÚ²¢ÐÐÇøÓòµÄÈë¿Ú´¦ÊÇ䶨ÒåµÄ£¬Ëü²¢²»»á¼Ì³ÐͬÃû¹²Ïí±äÁ¿µÄÖµ¡£
privateÉùÃ÷µÄ˽ÓбäÁ¿²»Äܼ̳ÐͬÃû±äÁ¿µÄÖµ£¬µ«Êµ¼ÊÇé¿öÖÐÓÐʱÐèÒª¼Ì³ÐÔÓй²Ïí±äÁ¿µÄÖµ£¬OpenMPÌṩÁËfirstprivate×Ó¾äÀ´ÊµÏÖÕâ¸ö¹¦ÄÜ¡£ÈôÉÏÊö³ÌÐòʹÓÃfirstprivate(k)£¬Ôò²¢ÐÐÇøÓòÄÚµÄ˽ÓбäÁ¿k¼Ì³ÐÁËÍâÃæ¹²Ïí±äÁ¿kµÄÖµ100×÷Ϊ³õʼֵ£¬²¢ÇÒÔÚÍ˳ö²¢ÐÐÇøÓòºó£¬¹²Ïí±äÁ¿kµÄÖµ±£³ÖΪ100δ±ä¡£
ÓÐʱÔÚ²¢ÐÐÇøÓòÄÚµÄ˽ÓбäÁ¿µÄÖµ¾¹ý¼ÆËãºó£¬ÔÚÍ˳ö²¢ÐÐÇøÓòʱ£¬ÐèÒª½«ËüµÄÖµ¸³¸øÍ¬ÃûµÄ¹²Ïí±äÁ¿£¬Ç°ÃæµÄprivateºÍfirstprivate×Ó¾äÔÚÍ˳ö²¢ÐÐÇøÓòʱ¶¼Ã»Óн«Ë½ÓбäÁ¿µÄ×îºóȡֵ¸³¸ø¶ÔÓ¦µÄ¹²Ïí±äÁ¿£¬lastprivate×Ó¾ä¾ÍÊÇÓÃÀ´ÊµÏÖÔÚÍ˳ö²¢ÐÐÇøÓòʱ½«Ë½ÓбäÁ¿µÄÖµ¸³¸ø¹²Ïí±äÁ¿¡£³ÌÐòʾÀýÈçÏ£º
int k = 100;
#pragma omp parallel for firstprivate(k),lastprivate(k)
for( i=0; i < 4; i++)
{
k+=i;
printf("k=%d/n",k);
}
printf("last k=%d/n", k);
|
ÉÏÃæ´úÂëÖ´ÐкóµÄ´òÓ¡½á¹ûÈçÏ£º
k=100
k=101
k=103
k=102
last k=103
|
´Ó´òÓ¡½á¹û¿ÉÒÔ¿´³ö£¬Í˳öforÑ»·µÄ²¢ÐÐÇøÓòºó£¬¹²Ïí±äÁ¿kµÄÖµ±ä³ÉÁË103£¬¶ø²»ÊDZ£³ÖÔÀ´µÄ100²»±ä¡£OpenMP¹æ·¶ÖÐÖ¸³ö£¬Èç¹ûÊÇÑ»·µü´ú£¬ÄÇôÊǽ«×îºóÒ»´ÎÑ»·µü´úÖеÄÖµ¸³¸ø¶ÔÓ¦µÄ¹²Ïí±äÁ¿£»Èç¹ûÊÇsection¹¹Ô죬ÄÇôÊÇ×îºóÒ»¸ösectionÓï¾äÖеÄÖµ¸³¸ø¶ÔÓ¦µÄ¹²Ïí±äÁ¿¡£×¢ÒâÕâÀï˵µÄ×îºóÒ»¸ösectionÊÇÖ¸³ÌÐòÓï·¨ÉϵÄ×îºóÒ»¸ö£¬¶ø²»ÊÇʵ¼ÊÔËÐÐʱµÄ×îºóÒ»¸öÔËÐÐÍêµÄ¡£Èç¹ûÊÇÀࣨclass£©ÀàÐ͵ıäÁ¿Ê¹ÓÃÔÚlastprivate²ÎÊýÖУ¬ÄÇôʹÓÃʱÓÐЩÏÞÖÆ£¬ÐèÒªÒ»¸ö¿É·ÃÎʵģ¬Ã÷È·µÄȱʡ¹¹Ô캯Êý£¬³ý·Ç±äÁ¿Ò²±»Ê¹ÓÃ×÷Ϊfirstprivate×Ó¾äµÄ²ÎÊý£»»¹ÐèÒªÒ»¸ö¿½±´¸³Öµ²Ù×÷·û£¬²¢ÇÒÕâ¸ö¿½±´¸³Öµ²Ù×÷·û¶ÔÓÚ²»Í¬¶ÔÏóµÄ²Ù×÷˳ÐòÊÇδָ¶¨µÄ£¬ÒÀÀµÓÚ±àÒëÆ÷µÄ¶¨Òå¡£
(6) threadprivate
threadprivateÖ¸ÁîÓÃÀ´Ö¸¶¨È«¾ÖµÄ¶ÔÏ󱻸÷¸öÏ̸߳÷×Ô¸´ÖÆÁËÒ»¸ö˽ÓеĿ½±´£¬¼´¸÷¸öÏ߳̾ßÓи÷×Ô˽ÓеÄÈ«¾Ö¶ÔÏó¡£threadprivateºÍprivateµÄÇø±ðÔÚÓÚthreadprivateÉùÃ÷µÄ±äÁ¿Í¨³£ÊÇÈ«¾Ö·¶Î§ÄÚÓÐЧµÄ£¬¶øprivateÉùÃ÷µÄ±äÁ¿Ö»ÔÚËüËùÊôµÄ²¢Ðй¹ÔìÖÐÓÐЧ¡£ÓÃ×÷threadprivateµÄ±äÁ¿µÄµØÖ·²»ÄÜÊdz£Êý¡£¶ÔÓÚC++µÄÀࣨclass£©ÀàÐͱäÁ¿£¬ÓÃ×÷threadprivateµÄ²ÎÊýʱÓÐЩÏÞÖÆ£¬µ±¶¨Òåʱ´øÓÐÍⲿ³õʼ»¯Ê±£¬±ØÐë¾ßÓÐÃ÷È·µÄ¿½±´¹¹Ô캯Êý¡£³ÌÐòʾÀýÈçÏ£º
int g;
#pragma omp threadprivate(g) //Ò»¶¨ÒªÏÈÉùÃ÷
int main(int argc, char *argv[])
{
/* Explicitly turn off dynamic threads */
omp_set_dynamic(0);
#pragma omp parallel
{
g = omp_get_thread_num();? ?
printf("tid: %d\n",g); //Ëæ»úÒÀ´ÎÊä³ö0~3
} // End of parallel region
#pragma omp parallel
{
int temp = g*g;
printf("tid : %d, tid*tid: %d\n",g,
temp); //²»Í¬Ïß³ÌÖÐÈ«¾Ö±äÁ¿Öµ²»Í¬
} // End of parallel region
}
|
×¢Ò⣺ÔÚʹÓÃthreadprivateµÄʱºò£¬ÒªÓÃomp_set_dynamic(0)¹Ø±Õ¶¯Ì¬Ï̵߳ÄÊôÐÔ£¬²ÅÄܱ£Ö¤½á¹ûÕýÈ·¡£
(7) Share
shared×Ó¾ä¿ÉÒÔÓÃÓÚÉùÃ÷Ò»¸ö»ò¶à¸ö±äÁ¿Îª¹²Ïí±äÁ¿¡£ËùνµÄ¹²Ïí±äÁ¿£¬ÊÇÖµÔÚÒ»¸ö²¢ÐÐÇøÓòµÄteamÄÚµÄËùÓÐÏß³ÌÖ»ÓµÓбäÁ¿µÄÒ»¸öÄÚ´æµØÖ·£¬ËùÓÐÏ̷߳ÃÎÊͬһµØÖ·¡£ËùÒÔ£¬¶ÔÓÚ²¢ÐÐÇøÓòÄڵĹ²Ïí±äÁ¿£¬ÐèÒª¿¼ÂÇÊý¾Ý¾ºÕùÌõ¼þ£¬Òª·ÀÖ¹¾ºÕù£¬ÐèÒªÔö¼Ó¶ÔÓ¦µÄ±£»¤¡£³ÌÐòʾÀýÈçÏ£º
#define COUNT
10000
int main(int argc, _TCHAR* argv[])
{
int sum = 0;
#pragma omp parallel for shared(sum)
for(int i = 0; i < COUNT;i++)
{
sum = sum + i;
}
printf("%d\n",sum);
return 0;
}
|
¶à´ÎÔËÐУ¬½á¹û¿ÉÄܲ»Ò»Ñù¡£ÐèҪעÒâµÄÊÇ£ºÑ»·µü´ú±äÁ¿ÔÚÑ»·¹¹ÔìÇøÓòÀïÊÇ˽Óеģ¬ÉùÃ÷ÔÚÑ»·¹¹ÔìÇøÓòÄÚµÄ×Ô¶¯±äÁ¿¶¼ÊÇ˽Óеġ£Èç¹ûÑ»·µü´ú±äÁ¿Ò²Êǹ²Óеģ¬OpenMP¸ÃÈçºÎÈ¥Ö´ÐУ¬ËùÒÔÒ²Ö»ÄÜÊÇ˽ÓеÄÁË¡£¼´Ê¹Ê¹ÓÃsharedÀ´ÐÞÊÎÑ»·µü´ú±äÁ¿£¬Ò²²»»á¸Ä±äÑ»·µü´ú±äÁ¿ÔÚÑ»·¹¹ÔìÇøÓòÖÐÊÇ˽ÓеÄÕâÒ»ÌØµã¡£³ÌÐòʾÀýÈçÏ£º
#define COUNT
10
int main(int argc, _TCHAR* argv[])
{
int sum = 0;
int i = 0;
#pragma omp parallel for shared(sum, i)
for(i = 0; i < COUNT;i++)
{
sum = sum + i;
}
printf("%d\n",i);
printf("%d\n",sum);
return 0;
}
|
ÉÏÊö³ÌÐòÖУ¬Ñ»·µü´ú±äÁ¿iµÄÊä³öֵΪ0£¬¾¡¹ÜÕâÀïʹÓÃsharedÐÞÊαäÁ¿i¡£×¢Ò⣬ÕâÀïµÄ¹æÔòÖ»ÊÇÕë¶ÔÑ»·²¢ÐÐÇøÓò£¬¶ÔÓÚÆäËûµÄ²¢ÐÐÇøÓòûÓÐÕâÑùµÄÒªÇó¡£Í¬Ê±ÔÚÑ»·²¢ÐÐÇøÓòÄÚ£¬Ñ»·µü´ú±äÁ¿ÊDz»¿ÉÐ޸ĵġ£¼´ÔÚÉÏÊö³ÌÐòÖУ¬²»ÄÜÔÙforÑ»·ÌåÄÚ¶ÔÑ»·µü´ú±äÁ¿i½øÐÐÐ޸ġ£
(8) Default
defaultÖ¸¶¨²¢ÐÐÇøÓòÄÚ±äÁ¿µÄÊôÐÔ£¬C++µÄOpenMPÖÐdefaultµÄ²ÎÊýÖ»ÄÜΪshared»ònone¡£default(shared)£º±íʾ²¢ÐÐÇøÓòÄڵĹ²Ïí±äÁ¿ÔÚ²»Ö¸¶¨µÄÇé¿ö϶¼ÊÇsharedÊôÐÔ
default(none)£º±íʾ±ØÐëÏÔʽָ¶¨ËùÓй²Ïí±äÁ¿µÄÊý¾ÝÊôÐÔ£¬·ñÔò»á±¨´í£¬³ý·Ç±äÁ¿ÓÐÃ÷È·µÄÊôÐÔ¶¨Ò壨±ÈÈçÑ»·²¢ÐÐÇøÓòµÄÑ»·µü´ú±äÁ¿Ö»ÄÜÊÇ˽Óеģ©Èç¹ûÒ»¸ö²¢ÐÐÇøÓò£¬Ã»ÓÐʹÓÃdefault×Ӿ䣬ÄÇôÆäĬÈÏÐÐΪΪdefault(shared)¡£
(9) Copyin
copyin×Ó¾äÓÃÓÚ½«Ö÷Ïß³ÌÖÐthreadprivate±äÁ¿µÄÖµ¿½±´µ½Ö´Ðв¢ÐÐÇøÓòµÄ¸÷¸öÏ̵߳Äthreadprivate±äÁ¿ÖУ¬´Ó¶øÊ¹µÃteamÄÚµÄ×ÓÏ̶߳¼ÓµÓкÍÖ÷Ïß³ÌͬÑùµÄ³õʼֵ¡£³ÌÐòʾÀýÈçÏ£º
#include <omp.h>
int A = 100;
#pragma omp threadprivate(A)?
int main(int argc, _TCHAR* argv[])
{
#pragma omp parallel for
for(int i = 0; i<10;i++)
{
A++;
printf("Thread ID: %d, %d: %d\n",omp_get_thread_num(),
i, A); // #1
}
|
printf("Global A: %d\n",A);
// ²¢ÐÐÇøÓòÍâµÄ´òÓ¡µÄ¡°Globa A¡±µÄÖµ×ÜÊǺÍÇ°ÃæµÄthread 0µÄ½á¹ûÏàµÈ£¬ÒòΪÍ˳ö²¢ÐÐÇøÓòºó£¬Ö»ÓÐmasterÏ̼߳´0ºÅÏß³ÌÔËÐС£
#pragma omp parallel
for copyin(A)
for(int i = 0; i<10;i++)
{
A++;
printf("Thread ID: %d, %d: %d\n",omp_get_thread_num(),
i, A); // #1
}
printf("Global A: %d\n",A); // #2
return 0;
}
|
²»Ê¹ÓÃcopyinµÄÇé¿öÏ£¬½øÈëµÚ¶þ¸ö²¢ÐÐÇøÓòµÄʱºò£¬²»Í¬Ï̵߳Ä˽Óи±±¾AµÄ³õʼֵÊDz»Ò»ÑùµÄ£¬ÕâÀïʹÓÃÁËcopyinÖ®ºó£¬·¢ÏÖËùÓеÄÏ̵߳ijõʼֵ¶¼Ê¹ÓÃÖ÷Ï̵߳ÄÖµ³õʼ»¯£¬È»ºó¼ÌÐøÔËË㣬Êä³öµÄÖµ¼´Îª±¾´Îthread
0µÄ½á¹û¡£¼òµ¥Àí½â£¬ÔÚʹÓÃÁËcopyinºó£¬ËùÓеÄÏ̵߳ÄthreadprivateÀàÐ͵ĸ±±¾±äÁ¿¶¼»áÓëÖ÷Ï̵߳ĸ±±¾±äÁ¿½øÐÐÒ»´Î¡°Í¬²½¡±¡£
ÁíÍâcopyinÖеIJÎÊý±ØÐë±»ÉùÃ÷³ÉthreadprivateµÄ£¬¶ÔÓÚÀàÀàÐ͵ıäÁ¿£¬±ØÐë´øÓÐÃ÷È·µÄ¿½±´¸³Öµ²Ù×÷·û¡£
(10) Copyprivate
copyprivate×Ó¾äÓÃÓÚ½«Ïß³Ì˽Óи±±¾±äÁ¿µÄÖµ´ÓÒ»¸öÏ̹߳㲥µ½Ö´ÐÐͬһ²¢ÐÐÇøÓòµÄÆäËûÏ̵߳Äͬһ±äÁ¿¡£copyprivateÖ»ÄÜÓÃÓÚsingleÖ¸ÁsingleÖ¸Áî:ÓÃÔÚÒ»¶ÎÖ»±»µ¥¸öÏß³ÌÖ´ÐеĴúÂë¶Î֮ǰ,±íʾºóÃæµÄ´úÂë¶Î½«±»µ¥Ïß³ÌÖ´ÐУ©µÄ×Ó¾äÖУ¬ÔÚÒ»¸ösingle¿éµÄ½áβ´¦Íê³É¹ã²¥²Ù×÷¡£copyprivateÖ»ÄÜÓÃÓÚprivate/firstprivate»òthreadprivateÐÞÊεıäÁ¿¡£³ÌÐòʾÀýÈçÏ£º
int counter
= 0;
#pragma omp threadprivate(counter)
int increment_counter()
{
counter++;
return(counter);
}
#pragma omp parallel
{
int count;
#pragma omp single copyprivate(counter)
{
counter = 50;
}
count = increment_counter();
printf("ThreadId: %ld, count = %ld/n",
omp_get_thread_num(), count);
}
|
´òÓ¡½á¹ûΪ£º
ThreadId: 2,
count = 51
ThreadId: 0, count = 51
ThreadId: 3, count = 51
ThreadId: 1, count = 51
|
Èç¹ûûÓÐʹÓÃcopyprivate×Ӿ䣬ÄÇô´òÓ¡½á¹ûΪ£º
ThreadId: 2,
count = 1
ThreadId: 1, count = 1
ThreadId: 0, count = 51
ThreadId: 3, count = 1
|
¿ÉÒÔ¿´³ö£¬Ê¹ÓÃcopyprivate×Ó¾äºó£¬single¹¹ÔìÄÚ¸øcounter¸³µÄÖµ±»¹ã²¥µ½ÁËÆäËûÏß³ÌÀµ«Ã»ÓÐʹÓÃcopyprivate×Ó¾äʱ£¬Ö»ÓÐÒ»¸öÏ̻߳ñµÃÁËsingle¹¹ÔìÄڵĸ³Öµ£¬ÆäËûÏß³ÌûÓлñÈ¡single¹¹ÔìÄڵĸ³Öµ¡£
6. OpenMPÖеÄÈÎÎñµ÷¶È
OpenMPÖУ¬ÈÎÎñµ÷¶ÈÖ÷ÒªÓÃÓÚ²¢ÐеÄforÑ»·ÖУ¬µ±Ñ»·ÖÐÿ´Îµü´úµÄ¼ÆËãÁ¿²»ÏàµÈʱ£¬Èç¹û¼òµ¥µØ¸ø¸÷¸öÏ̷߳ÖÅäÏàͬ´ÎÊýµÄµü´úµÄ»°£¬»áÔì³É¸÷¸öÏ̼߳ÆËã¸ºÔØ²»¾ùºâ£¬Õâ»áʹµÃÓÐЩÏß³ÌÏÈÖ´ÐÐÍ꣬ÓÐЩºóÖ´ÐÐÍ꣬Ôì³ÉijЩCPUºË¿ÕÏУ¬Ó°Ïì³ÌÐòÐÔÄÜ¡£OpenMPÌṩÁËschedule×Ó¾äÀ´ÊµÏÖÈÎÎñµÄµ÷¶È¡£schedule×Ó¾ä¸ñʽ£ºschedule(type,[size])¡£
¡¡¡¡²ÎÊýtypeÊÇÖ¸µ÷¶ÈµÄÀàÐÍ£¬¿ÉÒÔȡֵΪstatic£¬dynamic£¬guided£¬runtimeËÄÖÖÖµ¡£ÆäÖÐruntimeÔÊÐíÔÚÔËÐÐʱȷ¶¨µ÷¶ÈÀàÐÍ£¬Òò´Ëʵ¼Êµ÷¶È²ßÂÔÖ»ÓÐÇ°ÃæÈýÖÖ¡£
¡¡¡¡²ÎÊýsize±íʾÿ´Îµ÷¶ÈµÄµü´úÊýÁ¿£¬±ØÐëÊÇÕûÊý¡£¸Ã²ÎÊýÊÇ¿ÉÑ¡µÄ¡£µ±typeµÄÖµÊÇruntimeʱ£¬²»Äܹ»Ê¹ÓøòÎÊý¡£
( 1) ¾²Ì¬µ÷¶Èstatic
´ó²¿·Ö±àÒëÆ÷ÔÚûÓÐʹÓÃschedule×Ó¾äµÄʱºò£¬Ä¬ÈÏÊÇstaticµ÷¶È¡£staticÔÚ±àÒëµÄʱºò¾ÍÒѾȷ¶¨ÁË£¬ÄÇЩѻ·ÓÉÄÄЩÏß³ÌÖ´ÐС£¼ÙÉèÓÐn´ÎÑ»·µü´ú£¬t¸öỊ̈߳¬ÄÇô¸øÃ¿¸öÏ߳̾²Ì¬·ÖÅä´óÔ¼n/t´Îµü´ú¼ÆËã¡£n/t²»Ò»¶¨ÊÇÕûÊý£¬Òò´Ëʵ¼Ê·ÖÅäµÄµü´ú´ÎÊý¿ÉÄÜ´æÔÚ²î1µÄÇé¿ö¡£
ÔÚ²»Ê¹ÓÃsize²ÎÊýʱ£¬·ÖÅä¸øÃ¿¸öÏ̵߳ÄÊÇn/t´ÎÁ¬ÐøµÄµü´ú£¬ÈôÑ»·´ÎÊýΪ10£¬Ïß³ÌÊýΪ2£¬ÔòÏß³Ì0µÃµ½ÁË0¡«4´ÎÁ¬Ðøµü´ú£¬Ïß³Ì1µÃµ½5¡«9´ÎÁ¬Ðøµü´ú¡£
µ±Ê¹ÓÃsizeʱ£¬½«Ã¿´Î¸øÏ̷߳ÖÅäsize´Îµü´ú¡£ÈôÑ»·´ÎÊýΪ10£¬Ïß³ÌÊýΪ2£¬Ö¸¶¨sizeΪ2Ôò0¡¢1´Îµü´ú·ÖÅ䏸Ïß³Ì0£¬2¡¢3´Îµü´ú·ÖÅ䏸Ïß³Ì1£¬ÒÔ´ËÀàÍÆ¡£
( 2) ¶¯Ì¬µ÷¶Èdynamic
¶¯Ì¬µ÷¶ÈÒÀÀµÓÚÔËÐÐʱµÄ״̬¶¯Ì¬È·¶¨Ïß³ÌËùÖ´Ðеĵü´ú£¬Ò²¾ÍÊÇÏß³ÌÖ´ÐÐÍêÒѾ·ÖÅäµÄÈÎÎñºó£¬»áÈ¥ÁìÈ¡»¹ÓеÄÈÎÎñ£¨Ó뾲̬µ÷¶È×î´óµÄ²»Í¬£¬Ã¿¸öÏß³ÌÍê³ÉµÄÈÎÎñÊýÁ¿¿ÉÄܲ»Ò»Ñù£©¡£ÓÉÓÚÏß³ÌÆô¶¯ºÍÖ´ÐÐÍêµÄʱ¼ä²»È·¶¨£¬ËùÒÔµü´ú±»·ÖÅäµ½ÄĸöÏß³ÌÊÇÎÞ·¨ÊÂÏÈÖªµÀµÄ¡£
µ±²»Ê¹ÓÃsize ʱ£¬Êǽ«µü´úÖð¸öµØ·ÖÅäµ½¸÷¸öÏ̡߳£µ±Ê¹ÓÃsize
ʱ£¬Öð¸ö·ÖÅäsize¸öµü´ú¸ø¸÷¸öỊ̈߳¬Õâ¸öÓ÷¨ÀàËÆ¾²Ì¬µ÷¶È¡£
(3) Æô·¢Ê½µ÷¶Èguided
²ÉÓÃÆô·¢Ê½µ÷¶È·½·¨½øÐе÷¶È£¬Ã¿´Î·ÖÅ䏸Ï̵߳ü´ú´ÎÊý²»Í¬£¬¿ªÊ¼±È½Ï´ó£¬ÒÔºóÖð½¥¼õС¡£¿ªÊ¼Ê±Ã¿¸öÏ̻߳á·ÖÅäµ½½Ï´óµÄµü´ú¿é£¬Ö®ºó·ÖÅäµ½µÄµü´ú¿é»áÖ𽥵ݼõ¡£µü´ú¿éµÄ´óС»á°´Ö¸Êý¼¶Ï½µµ½Ö¸¶¨µÄsize´óС£¬Èç¹ûûÓÐÖ¸¶¨size²ÎÊý£¬ÄÇôµü´ú¿é´óС×îС»á½µµ½1¡£
size±íʾÿ´Î·ÖÅäµÄµü´ú´ÎÊýµÄ×îСֵ£¬ÓÉÓÚÿ´Î·ÖÅäµÄµü´ú´ÎÊý»áÖð½¥¼õÉÙ£¬ÉÙµ½sizeʱ£¬½«²»ÔÙ¼õÉÙ¡£¾ßÌå²ÉÓÃÄÄÒ»ÖÖÆô·¢Ê½Ëã·¨£¬ÐèÒª²Î¿¼¾ßÌåµÄ±àÒëÆ÷ºÍÏà¹ØÊÖ²áµÄÐÅÏ¢¡£
(4) µ÷¶È·½Ê½×ܽá
¾²Ì¬µ÷¶Èstatic£ºÃ¿´ÎÄÄЩѻ·ÓÉÄǸöÏß³ÌÖ´ÐÐʱ¹Ì¶¨µÄ£¬±àÒëµ÷ÊÔ¡£ÓÉÓÚÿ¸öÏ̵߳ÄÈÎÎñÊǹ̶¨µÄ£¬µ«ÊÇ¿ÉÄÜÓеÄÑ»·ÈÎÎñÖ´Ðп죬ÓеÄÂý£¬²»ÄÜ´ïµ½×îÓÅ¡£
¶¯Ì¬µ÷¶Èdynamic£º¸ù¾ÝÏ̵߳ÄÖ´ÐпìÂý£¬ÒѾÍê³ÉÈÎÎñµÄÏ̻߳á×Ô¶¯ÇëÇóеÄÈÎÎñ»òÕßÈÎÎñ¿é£¬Ã¿´ÎÁìÈ¡µÄÈÎÎñ¿éÊǹ̶¨µÄ¡£
Æô·¢Ê½µ÷¶Èguided£ºÃ¿¸öÈÎÎñ·ÖÅäµÄÈÎÎñÊÇÏÈ´óºóС£¬Ö¸ÊýϽµ¡£µ±ÓдóÁ¿ÈÎÎñÐèҪѻ·Ê±£¬¸Õ¿ªÊ¼ÎªÏ̷߳ÖÅä´óÁ¿ÈÎÎñ£¬×îºóÈÎÎñ²»¶àʱ£¬¸øÃ¿¸öÏß³ÌÉÙÁ¿ÈÎÎñ£¬¿ÉÒÔ´ïµ½Ïß³ÌÈÎÎñ¾ùºâ¡£
OpenMP³ÌÐòÉè¼Æ¼¼ÇÉ×ܽá
1.µ±Ñ»·´ÎÊý½ÏÉÙʱ£¬Èç¹û·Ö³É¹ý¶àµÄÏß³ÌÀ´Ö´Ðеϰ£¬¿ÉÄÜ»áʹµÃ×ܵÄÔËÐÐʱ¼ä¸ßÓÚ½ÏÉÙÏ̻߳òÒ»¸öÏ̵߳ÄÖ´ÐÐÇé¿ö£¬²¢ÇÒ»áÔö¼ÓÄܺģ»
2.Èç¹ûÉèÖõÄÏß³ÌÊýÁ¿Ô¶´óÓÚCPUµÄºËÊýµÄ»°£¬ÄÇô´æÔÚ×Å´óÁ¿µÄÈÎÎñÇл»ºÍµ÷¶ÈµÄ¿ªÏú£¬Ò²»á½µµÍÕûÌåµÄЧÂÊ¡£
3.ÔÚǶÌ×Ñ»·ÖУ¬Èç¹ûÍâ²ãÑ»·µü´ú´ÎÊý½ÏÉÙʱ£¬Èç¹û½«À´CPUºËÊýÔö¼Óµ½Ò»¶¨³Ì¶Èʱ£¬´´½¨µÄÏß³ÌÊý½«¿ÉÄÜСÓÚCPUºËÊý¡£ÁíÍâÈç¹ûÄÚ²ãÑ»·´æÔÚ¸ºÔØÆ½ºâµÄÇé¿öÏ£¬ºÜÄѵ÷¶ÈÍâ²ãÑ»·Ê¹Ö®´ïµ½¸ºÔØÆ½ºâ¡£
|