Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Model Center   Code  
»áÔ±   
   
 
     
   
 ¶©ÔÄ
  ¾èÖú
OpenMPÓ÷¨´óÈ«£¨¸öÈËÕûÀí°æ£©
 
  11126  次浏览      28
 2018-11-7 
 
±à¼­ÍƼö:
±¾ÎÄÀ´×ÔÓÚ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ºËÊý¡£ÁíÍâÈç¹ûÄÚ²ãÑ­»·´æÔÚ¸ºÔØÆ½ºâµÄÇé¿öÏ£¬ºÜÄѵ÷¶ÈÍâ²ãÑ­»·Ê¹Ö®´ïµ½¸ºÔØÆ½ºâ¡£

   
11126 ´Îä¯ÀÀ       28
Ïà¹ØÎÄÕÂ

Éî¶È½âÎö£ºÇåÀíÀôúÂë
ÈçºÎ±àд³öÓµ±§±ä»¯µÄ´úÂë
ÖØ¹¹-ʹ´úÂë¸ü¼ò½àÓÅÃÀ
ÍŶÓÏîÄ¿¿ª·¢"±àÂë¹æ·¶"ϵÁÐÎÄÕÂ
Ïà¹ØÎĵµ

ÖØ¹¹-¸ÄÉÆ¼ÈÓдúÂëµÄÉè¼Æ
Èí¼þÖØ¹¹v2
´úÂëÕû½àÖ®µÀ
¸ßÖÊÁ¿±à³Ì¹æ·¶
Ïà¹Ø¿Î³Ì

»ùÓÚHTML5¿Í»§¶Ë¡¢Web¶ËµÄÓ¦Óÿª·¢
HTML 5+CSS ¿ª·¢
ǶÈëʽC¸ßÖÊÁ¿±à³Ì
C++¸ß¼¶±à³Ì