´ÙÀ½ ÀÌÀü Â÷·Ê

4. °íÇØ»óµµ Å¸À̹Ö: Áö¿¬ ½Ã°£

¿ì¼±, ¸®´ª½ºÀÇ ¼±Á¡Çü ¸ÖƼŽºÅ· ¶§¹®¿¡ »ç¿ëÀÚ ¸ðµåÀÇ ÇÁ·Î¼¼½º°¡ ŸÀ̹ÖÀ» Á¤È®È÷ Á¦¾îÇÏ´ÂÁö º¸ÁõÇÒ ¼ö ¾ø´Ù´Â °Í¿¡ ÁÖÀÇÇÑ´Ù. ¹«¾ùº¸´Ùµµ, »ç¿ëÀÚ ¸ðµåÀÇ ÇÁ·Î¼¼½º´Â ¸ÖƼ ŽºÅ·°ú ¸®´ª½ºÀÇ ¼±Á¡ÀûÀΠƯ¼º ¶§¹®¿¡ Á¤È®ÇÑ Å¸À̹ÖÀ» º¸ Àå¹ÞÀ» ¼ö ¾ø´Ù´Â °ÍÀ» ¸»ÇÏ°í ½Í´Ù. ¿©·¯ºÐÀÇ ÇÁ·Î¼¼½º°¡ 10¹Ð¸® ÃÊ¿¡¼­ (·Îµå °¡ Å©°Ô °É¸®´Â ½Ã½ºÅÛ¿¡¼­) ¼ö Ãʵ¿¾È ½ºÄÉÁ층¿¡¼­ Á¦¿ÜµÉ ¼ö ÀÖ´Ù. ±×·¯³ª, I/O Æ÷Æ®¸¦ »ç¿ëÇÏ´Â ´ëºÎºÐÀÇ ÀÀ¿ë ÇÁ·Î±×·¥¿¡¼­ ÀÌ´Â º°·Î ¹®Á¦°¡ µÇÁö ¾Ê´Â ´Ù. ÀÌ·¯ÇÑ ¹®Á¦¸¦ ÃÖ¼ÒÈ­ ÇÏ·Á¸é ¿©·¯ºÐÀÇ ÇÁ·Î¼¼½º¸¦ nice ¸í·É¾î·Î ³ôÀº ¿ì¼± ¼øÀ§¸¦ ºÎ¿©ÇÒ ¼ö ÀÖ´Ù. (nice(2)ÀÇ ¸Å´º¾ó ÆäÀÌÁö¸¦ ÂüÁ¶Çϱ⠹ٶõ´Ù).

ÀÏ¹Ý »ç¿ëÀÚ ¸ðµåÀÇ ÇÁ·Î¼¼½º¸¦ Á¤È®ÇÑ Å¸À̹ÖÀ¸·Î ¼öÇà½ÃÅ°·Á ÇÑ´Ù¸é, »ç¿ëÀÚ ¸ðµåÀÇ `¸®¾ó ŸÀÓ' ±â´ÉÀÌ Áö¿øµÇ¾î¾ß ÇÑ´Ù. ¸®´ª½º 2.x Ä¿³Î¿¡¼­´Â ¼ÒÇÁÆ® ¸® ¾ó ŸÀÓ ±â´ÉÀÌ Áö¿øµÇ¾î¾ß ÇÑ´Ù; ÀÚ¼¼ÇÑ °ÍÀº sched_setscheduler(2) ¸ÇÆäÀÌÁö ¸¦ ÂüÁ¶ÇÑ´Ù. ÇÏµå ¸®¾ó ŸÀÓÀ» Áö¿øÇϴ Ưº°ÇÑ Ä¿³ÎÀÌ ÀÖ´Ù. ÀÌ¿¡ ´ëÇÑ ´õ ¸¹ Àº Á¤º¸´Â <URL: luz.cs.nmt.edu/~rtlinux/>¸¦ ÂüÁ¶ÇÑ´Ù. ÀÌÁ¦, ´õ ½¬¿î ŸÀÌ¹Ö È£ÃâÀ» ½ÃÀÛÇØ º¸ÀÚ. ¸îÃʵ¿¾È Áö¿¬ÇÏ·Á¸é, ÃÖ¼±ÀÇ ¼±ÅÃÀº sleep(3)¸¦ »ç¿ëÇÏ´Â °ÍÀÌ´Ù. ÃÖ¼ÒÇÑ ¼ö½Ê Ãʸ¦ Áö¿¬ÇÏ·Á¸é (ÃÖ¼Ò Áö¿¬ ½Ã°£ÀÌ 10 ¹Ð¸®ÃÊ Á¤µµ µÉ ¶§), usleep(3)°¡ ±×·¸°Ô µ¿ÀÛÇÒ °ÍÀÌ´Ù. ÀÌ·¯ÇÑ ±â´ÉÀº CPU¿¡°Ô ´Ù¸¥ ÇÁ·Î¼¼½º¸¦ ¼öÇàÇϵµ·Ï ÇϹǷÎ, CPU ŸÀÓÀÌ ³¶ºñµÇ´Â ÀÏÀÌ ¾ø´Ù. ÀÚ¼¼ÇÑ °ÍÀº ¸Å´º¾ó ÆäÀÌÁö¸¦ ÂüÁ¶ÇÑ´Ù.

50¹Ð¸®ÃÊ ÀÌÇÏ·Î Áö¿¬ÇÒ ¶§´Â (ÇÁ·Î¼¼¼­³ª ¸Ó½Å, ½Ã½ºÅÛ ºÎÇÏ¿¡ Á¿ìµÇÁö¸¸), ¸® ´ª½º ½ºÄÉÁì·¯´Â Á¦¾î±ÇÀ» µ¹·Á ¹Þ±â Àü¿¡ ÃÖ¼ÒÇÑ 10-30 ¹Ð¸®ÃÊ Á¤µµ ¼Ò¸ðÇϱ⠶§¹®¿¡ CPU¸¦ Æ÷±âÇÒ ¼ö´Â ¾ø´Ù. ÀÌ·¯ÇÑ ÀÌÀ¯ ¶§¹®¿¡, ¾ÆÁÖ ÀÛÀº Áö¿¬ ½Ã°£À» µÑ ¶§, usleep(3)Àº ¸Å°³º¯¼ö¿¡ ÁöÁ¤ÇÑ °Í º¸´Ù ÃÖ¼Ò 10¹Ð¸®ÃÊ Á¤µµ ´õ Áö¿¬À» ÇÑ´Ù.

ªÀº Áö¿¬ ½Ã°£À» ÇÒ´çÇÒ °æ¿ì (º¸Åë 50¹Ð¸®ÃÊ Á¤µµ µÉ °ÍÀÌ´Ù), ´Ù¾çÇÏ°Ô ¾²ÀÏ ¼ö ÀÖ´Â ¹æ¹ýÀº udelay()¸¦ »ç¿ëÇÏ´Â °ÍÀε¥, /usr/include/asm/delay.h (linux/include/asm-i386/delay.h) ¿¡ Á¤ÀǵǾî ÀÖ´Ù. udelay()´Â ¸Å°³º¯¼ö¸¦ Çϳª ¸¸ ÁÖ¾úÀ» ¶§ Áö¿¬Çϴµ¥ ¸î ¸¶ÀÌÅ©·Î ÃÊ Á¤µµÀÇ ½Ã°£ÀÌ °É¸®°í, ¾Æ¹«°Íµµ ¸®ÅÏ ÇÏÁö ¾Ê´Â´Ù. ¸Å°³º¯¼ö¿¡¼­ ÁöÁ¤ÇÑ °Íº¸´Ù ¸î ¸¶ÀÌÅ©·ÎÃÊ Á¤µµ ´õ °É¸± ¼öµµ ÀÖ ´Âµ¥, ÀÌ´Â ¾ó¸¶³ª ±â´Ù·Á¾ß ÇÏ´ÂÁö °è»êÇÏ´Â ¿À¹öÇìµå¿¡¼­ ºñ·ÔµÈ °ÍÀÌ´Ù (delay.h¿¡ ÀÚ¼¼ÇÑ »çÇ×ÀÌ ÀÖ´Ù).

Ä¿³Î ¹Û¿¡¼­ udelay()¸¦ »ç¿ëÇϱâ À§Çؼ­, ¿©·¯ºÐÀº Á¤È®ÇÑ °ªÀ¸·Î Á¤ÀÇÇÑ unsigned long º¯¼öÀÎ loops_per_sec¸¦ ÇÊ¿ä·Î ÇÒ °ÍÀÌ´Ù. ÇÊÀÚ°¡ ¾Æ´Â ÇÑ, ÀÌ °ªÀ» Ä¿³Î¿¡¼­ ¾ò´Â °¡Àå ºü¸¥ ±æÀº /proc/cpuinfoÀÇ BogoMips¸¦ Àоî 500000À» °öÇÏ´Â °ÍÀÌ´Ù.

¸®´ª½º Ä¿³Î 2.0.x ½Ã¸®Áî¿¡¼­, »õ·Î¿î ½Ã½ºÅÛ È£ÃâÀÎ nanosleep(2) (¸ÇÆäÀÌÁö Âü Á¶)´Â ¸Å¿ì ªÀº ½Ã°£ µ¿¾È Àáµé°Å³ª Áö¿¬Çϵµ·Ï ÇÒ ¼ö ÀÖ´Ù. ÀÌ°ÍÀº ÇÁ·Î¼¼½º°¡ ¼ÒÇÁÆ® ¸®¾ó ŸÀÓ ½ºÄÉÁ층(sched_setscheduler(2)À» »ç¿ë)À» ÁöÁ¤ÇÑ´Ù¸é Áö¿¬ ½Ã°£ÀÌ 2 ¹Ð¸®ÃÊ ÀÌÇÏÀÏ ¶§ udelay(2)¸¦ »ç¿ëÇÏ°í, ´Ù¸¥ °æ¿ì¿¡´Â (usleep()¿Í °° ÀÌ) sleepÀ» È£ÃâÇÑ´Ù. ¿©·¯ºÐÀº nanosleep()¸¦ »ç¿ëÇϱâ À§Çؼ­ loops_per_sec º¯¼ö¸¦ ÇÊ¿ä·Î ÇÏÁö´Â ¾ÊÀ» °ÍÀε¥, ÀÌ ½Ã½ºÅÛ È£ÃâÀÌ ±× °ªÀ» Ä¿³Î¿¡¼­ °¡Á®¿À ±â ¶§¹®ÀÌ´Ù.

¼ö ¸¶ÀÌÅ©·ÎÃʵ¿¾È Áö¿¬ÇÏ´Â ¶Ç´Ù¸¥ ¹æ¹ýÀº Æ÷Æ® I/OÀÌ´Ù. Æ÷Æ® 0x80¿¡ ¸î ¹ÙÀÌ Æ®¸¦ ÀÐ°í ¾²·Á¸é ÇÁ·Î¼¼¼­ Á¾·ù³ª ¼Óµµ¿¡ °ü°è¾øÀÌ Á¤È®È÷ 1 ¸¶ÀÌÅ©·ÎÃÊ Á¤µµ ±â´Ù·Á¾ß ÇÑ´Ù. ¸î ¸¶ÀÌÅ©·ÎÃʵ¿¾È ±â´Ù¸®±â À§Çؼ­ ¿©·¯ ¹ø È£ÃâÇÒ ¼ö ÀÖ´Ù. ÀÌ Æ÷Æ® Ãâ·ÂÀº Ç¥ÁØ ¸Ó½Å¿¡ ´ëÇؼ­´Â ½É°¢ÇÑ ºÎÀÛ¿ëÀÌ ¾ø´Ù°í È®½ÅÇÑ´Ù.) (±×¸®°í Ä¿³Î µå¶óÀ̹öµµ À̸¦ »ç¿ëÇÑ´Ù.) ÀÌ´Â {in|out}[bw]_p()°¡ Áö¿¬ÇÏ´Â ¹æ¹ýÀÌ´Ù (asm/io.h¸¦ ÂüÁ¶).

»ç½Ç, ´ëºÎºÐÀÇ ¹üÀ§ 0-0x3ff¹øÀÇ Æ÷Æ®¿¡¼­ ¾²´Â Æ÷Æ® I/O ¸í·ÉÀº °ÅÀÇ Á¤È®È÷ 1 ¸¶ÀÌÅ©·ÎÃÊ Á¤µµ Á¡À¯ÇϹǷÎ, ¿¹¸¦ µé¾î ¿©·¯ºÐÀÌ º´·Ä Æ÷Æ®¸¦ Á¤È®È÷ »ç¿ëÇÏ·Á ¸é Æ÷Æ®¿¡ Áö¿¬ ½Ã°£À» ÁÖ±â À§Çؼ­ Ãß°¡·Î inb()¸¦ È£ÃâÇÑ´Ù. ¿©·¯ºÐÀÌ ÇÁ·Î±×·¥ÀÌ µ¹¾Æ°¥ ÇÁ·Î¼¼¼­ÀÇ Á¾·ù³ª Ŭ·° ¼Óµµ¸¦ ¾Ë°í ÀÖ´Ù¸é, ƯÁ¤ ÇÑ ¾î¼Àºí·¯ ¸í·É¿¡¼­ ¿À´Â Áö¿¬ ½Ã°£º¸´Ù ´õ ªÀº ½Ã°£À» ½á³ÖÀ»(hard-code) ¼ö ÀÖ´Ù(±×·¸Áö¸¸ ±â¾ïÇÒ °ÍÀÌ ÀÖ´Ù¸é ÇÁ·Î¼¼½º´Â ¾ðÁ¦³ª ¼öÇàµÉ ¼ö ÀÖÀ¸¹Ç·Î, ±× Áö¿¬ ½Ã°£Àº ½ÇÁ¦·Î ´õ ±æ¾îÁú ¼ö ÀÖ´Ù´Â °ÍÀÌ´Ù). ¾Æ·¡ÀÇ Ç¥¿¡¼­ ³»ºÎ ÇÁ·Î ¼¼¼­ ¼Óµµ´Â Ŭ·° »çÀÌŬÀÇ ¼ö¸¦ °áÁ¤ÇÑ´Ù. ¿¹¸¦ µé¾î, 50 MHzÀÇ ÇÁ·Î¼¼¼­ (486DX-50 ¶Ç´Â 486DX2-50)ÀÇ Å¬·° »çÀÌŬÀº 1/50000000ÀÌ´Ù.


¸í·É          i386 Ŭ·° »çÀÌŬ     i486 Ŭ·° »çÀÌŬ
nop                   3                   1
xchg %ax,%ax          3                   3
or %ax,%ax            2                   1
mov %ax,%ax           2                   1
add %ax,0             2                   1

(¹Ì¾ÈÇÏÁö¸¸, ÆæƼ¾öÀÇ °æ¿ì´Â Àß ¸ð¸¥´Ù. ¾Æ¸¶µµ 486°ú ºñ½ÁÇÒ °ÍÀÌ´Ù.) (ÇÊÀÚ´Â i386¿¡¼­ ÇÑ »çÀÌŬÀ» »ç¿ëÇÏ´Â ¸í·ÉÀ» ãÀ» ¼ö ¾ø¾ú´Ù) Ç¥ÀÇ nop¿Í xchg ¸í·ÉÀº ºÎÀÛ¿ëÀÌ ¾ø´Ù. ³ª¸ÓÁö ¸í·ÉÀº Ç÷¡±× ·¹Áö½ºÅ͸¦ º¯°æ ÇÒ ¼ö ÀÖÁö¸¸, gcc°¡ ±×°ÍÀ» ¹ß°ßÇÑ´Ù°í ¹®Á¦°¡ µÇÁö´Â ¾Ê´Â´Ù. À̸¦ »ç¿ëÇÏ·Á¸é, ÇÁ·Î±×·¥¿¡¼­ asm("¸í·É"); À» È£ÃâÇÑ´Ù. À§ÀÇ Å×ÀÌºí¿¡¼­ ¹® ¹ý¿¡ ÀÖ´Â ¸í·ÉÀ» ÁØ´Ù; ¿©·¯ ¸í·ÉÀ» ³ÖÀ¸·Á¸éasm("¸í·É ; ¸í·É ; ¸í·É"); ÀÌ µÈ ´Ù. asm()Àº gcc°¡ ÀζóÀÎ ¾î¼Àºí¸®·Î º¯È¯ÇÏ¿© ÇÔ¼ö È£Ãâ ¿À¹öÇìµå°¡ ¾ø´Ù. ÆæƼ¾ö¿¡¼­, ´ÙÀ½°ú °°Àº C ÄÚµå·Î, ÃÖ±Ù¿¡ ¸®ºÎÆ® ÇÏ¿´À» ¶§ºÎÅÍ °æ°úÇÑ Å¬·° »çÀÌŬÀÇ ¼ö¸¦ ¾òÀ» ¼ö ÀÖ´Ù.

extern __inline__ unsigned long long int rdtsc() { unsigned long long int x; __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x)); return x; }

ÀÎÅÚ x86¾ÆÅ°ÅØó¿¡¼­ ÇÑ Å¬·° »çÀÌŬº¸´Ù ´õ ªÀº Áö¿¬ ½Ã°£À» ³»±â´Â ºÒ°¡´É ÇÏ´Ù.


´ÙÀ½ ÀÌÀü Â÷·Ê