#title 32bit ¿¡¼­ 64bit·Î ¼Ò½ºÈ£È¯À» À§ÇÑ °í·Á»çÇ× Á¤¸® == 32bit ¿¡¼­ 64bit·Î ¼Ò½ºÈ£È¯À» À§ÇÑ °í·Á»çÇ× Á¤¸® == * ÀÛ¼ºÀÚ Á¶ÀçÇõ ([mailto:minzkn@minzkn.com]) * °íÄ£°úÁ¤ 2007³â 6¿ù 17ÀÏ : óÀ½¾¸ === °³¿ä === ÀÌ ³»¿ëÀº Á¦°¡ ±âÁ¸¿¡ ¸¸µé¾ú´ø ¿©·¯ ¼Ò½º(mzapi) µéÀ» 64bit ¿¡¼­ µ¿ÀÛÇϵµ·Ï Æ÷ÆÃÇϸ鼭 ¹ß»ýÇß´ø °í·Á»çÇ×µéÀ» Á¤¸®ÇÕ´Ï´Ù. === º¯¼öÇüÀÇ Å©±â´Â ¾î¶»°Ô ´Þ¶óÁö´Â°¡? 32bit ȯ°æ¿¡¼­ 64bit ȯ°æÀ¸·Î ¿Å°Ü°¡¸é¼­ ´Þ¶óÁø º¯¼öÇüÀº ´ÙÀ½°ú °°½À´Ï´Ù. === 1. int ÇüÀº 32bit ¸¦ À¯ÁöÇÕ´Ï´Ù. 1. short ÇüÀº 16bit ¸¦ À¯ÁöÇÕ´Ï´Ù. 1. long ÇüÀº 32bit¿¡¼­ 64bit·Î È®ÀåµË´Ï´Ù. 1. long long ÇüÀº 64bit ¸¦ À¯ÁöÇÕ´Ï´Ù. 1. pointer ÇüÀº 32bit ¿¡¼­ 64bit·Î È®Àåµö´Ï´Ù. 1. long double ÇüÀÌ 12bytes ¿¡¼­ 16bytes·Î È®ÀåµË´Ï´Ù. 1. size_t°ú ssize_t ÇüÀÌ 32bit ¿¡¼­ 64bit ·Î È®ÀåµË´Ï´Ù. 1. ÀÌ¿Í °ü·ÃµÈ typedef ¹® ¿ª½Ã È®ÀåµË´Ï´Ù. === 64bit linux platforms === {{{ Architecture | uname -m | Size | Endian | Libpath | Miscellaneous ----------------+----------+------+--------+---------+-------------------------------- Alpha | alpha | LP64 | little | lib | AMD64 | x86_64 | LP64 | little | lib64 | executes x86 code natively IPF | ia64 | LP64 | little | lib | executes x86 code via emulation MIPS64 | mips64 | LP64 | both | lib64 | executes MIPS code natively PowerPC64 | ppc64 | LP64 | big | lib64 | executes PowerPC code natively Sparc64 | sparc64 | LP64 | big | lib64 | executes Sparc code natively PA-RISC64 | parisc64 | LP64 | big | - | only kernel support, no 64-bit | | | | | executes 32-bit PA-RISC code zSeries (s390x) | s390x | LP64 | big | lib64 | executes s390 code natively }}} === ¹®Á¦°¡ µÇ´Â ÄÚµåµé === ==== Å©±â°¡ ´Ù¸¥ º¯¼öÇü¿¡ ´ëÇÑ Æ÷ÀÎÅ͸¦ »ç¿ëÇÑ °æ¿ì (½ºÅúر«°¡ ¿ì·ÁµÇ´Â °æ¿ì) ==== getsockoptÀÇ sizeÀÎÀÚ°¡ socklen_t ·Î Á¤ÀǵǴ °æ¿ì ¾Æ·¡ÀÇ ÄÚµå´Â s_socklen º¯¼ö¸¦ int·Î Á¤ÀÇÇÑ°Í¿¡¼­ ¹®Á¦°¡ ¹ß»ýÇÒ¼ö ÀÖ½À´Ï´Ù. {{{ int s_socklen; s_result = getsockopt(s_socket, s_level, s_optname, &s_optval, &s_socklen); }}} ÀÌ°ÍÀº ´ÙÀ½°ú °°ÀÌ º¯°æµÇ¾î¾ß ÇÕ´Ï´Ù. ÀÌ°ÍÀº int¿Í socklen_t ´Â Å©±â°¡ ´Ù¸£±â ¶§¹®ÀÔ´Ï´Ù. {{{ socklen_t s_socklen; s_result = getsockopt(s_socket, s_level, s_optname, &s_optval, &s_socklen); }}} Á¶°Ç½ÄÀ» int ·Î ¹Þ´Â ÇÔ¼ö¿¡ Æ÷ÀÎÅ͸¦ ³Ñ°ÜÁÙ°æ¿ì (ÄÄÆÄÀÏ·¯ °æ°í) ÀϹÝÀûÀ¸·Î ´ÙÀ½°ú °°Àº ÇÔ¼ö°¡ ÀÖÀ»¶§ {{{ void my_assert(int s_expression) { if(!s_expression)return; (void)fprintf(stderr, "assert....\n"); } }}} À§¿Í °°Àº ÇÔ¼ö¿¡ Á¶°Ç¹®À» »ç¿ëÇÒ¶§ {{{ void *s_ptr = NULL; my_assert(s_ptr); }}} ´ÙÀ½°ú °°ÀÌ º¯°æÇÏ¿©¾ß ÇÕ´Ï´Ù. ÀÌ°ÍÀº Æ÷ÀÎÅÍ°¡ int Çü°ú ´Ù¸¥ Å©±âÀ̹ǷΠÆ÷ÀÎÅÍ´Â int·Î casting µÇ¸é¼­ À߸®°Ô µÇ°í NULLÆ÷ÀÎÅÍ°¡ ¾Æ´Ô¿¡µµ ÇÏÀ§ 32bit°¡ 0Àΰæ¿ì my_assert ´Â ÀǵµÇÏÁö ¾ÊÀº µ¿ÀÛÀ» ÇÒ¼ö Àֱ⠶§¹®ÀÔ´Ï´Ù. {{{ void *s_ptr = NULL; my_assert(s_ptr != NULL); }}} ==== dword Á¤ÀÇ (¸¸¾à ÀÌ·¸°Ô ½á¿Ô´Ù¸é..) ==== ´ÙÀ½°ú °°ÀÌ my_DWORD¸¦ Á¤ÀÇÇÏ¿© »ç¿ëÇß´Ù¸é {{{ #define my_DWORD unsigned long int }}} ´ÙÀ½°ú °°ÀÌ º¯°æÇÏ¿©¾ß ÇÕ´Ï´Ù. {{{ #define my_DWORD unsigned int }}} ==== x86°è¿­ ¾î¼Àºí¸® ȣȯ¼º (¾È¹Ù²ãµµ µ¿ÀÛÇÑ´Ù.) ==== ¿¹¸¦ µé¾î¼­ atomic exchange ¸¦ ´ÙÀ½°ú °°ÀÌ CÇÔ¼ö·Î ±¸ÇöÇß´Ù¸é ÀüÇô ¼öÁ¤ÇÒ ÇÊ¿ä¾øÀÌ ±×´ë·Î ÄÄÆÄÀÏ °¡´ÉÇÕ´Ï´Ù. ÇÏÁö¸¸ intÇüÀÌ ¾Æ´Ñ long ÇüÀ» »ç¿ëÇß´Ù¸é register ´Â eax, ebx, .. °¡ ¾Æ´Ñ rax, rbx, ... ·Î º¯°æÀ» °í·ÁÇØ¾ß ÇÕ´Ï´Ù. {{{ int my_atomic_exchange(int * volatile s_to, int s_value) { __asm volatile ("xchgl (%2), %0\n\t" : "=r"(s_value) : "0"(s_value), "r"(s_to) : "memory"); return(s_value); } }}} ==== implementation ÇÔ¼öÀÇ À߸øµÈ °í·Á (size_t µîÀÇ Àǹ̸¦ ÀüÇô È°¿ëÇÏÁö ¸øÇÑ°æ¿ì Æ÷ÆÃÀÌ ½±Áö ¾ÊÀ»¼ö ÀÖÀ½.) ==== ¿¹¸¦ µé¾î¼­ memcpy ¸¦ Çѹø °¨½Î¼­ ´ÙÀ½°ú °°ÀÌ ÀڽŸ¸ÀÇ ÇÔ¼ö¸¦ ¸¸µé¾ú´Ù¸é {{{ void *my_memcpy(void *s_to, const void *s_from, int s_size) { return(memcpy(s_to, s_from, s_size)); } }}} ´ç¿¬È÷ s_size º¯¼ö´Â 64bit¸¦ ´ãÀ»¼ö ¾ø´Â ±×¸©À¸·Î Àü´ÞµÇ±â ¶§¹®¿¡ ¿øÇÏÁö ¾ÊÀº °á°ú¸¦ ¹ß»ýÇÒ¼ö ÀÖ½À´Ï´Ù. ¶§¹®¿¡ ´ÙÀ½°ú °°ÀÌ º¯°æµÇ¾î¾ß ÇÕ´Ï´Ù. {{{ void *my_memcpy(void *s_to, const void *s_from, size_t s_size) { return(memcpy(s_to, s_from, s_size)); } }}} size_t, ssize_t ÀÇ ¿ëµµ¸¦ ÀüÇô Áß¿äÇÏ°Ô »ý°¢Áö ¾ÊÀº °³¹ßÀÚ¶ó¸é ÀÌ ¹®Á¦·Î 64bit Æ÷Æÿ¡ ÁÂÀýÀ» °ÞÀ»¼öµµ ÀÖ½À´Ï´Ù. °í·ÁÇÏÁö ¾ÊÀº °³¹ßÀںеéÀº À§ÀÇ ¿¹Á¦Ã³·³ memcpy ¿¡¼­º¸´Ù´Â memory offset ¿¬»ê¿¡¼­ ÈÄȸÇÒ¼ö ÀÖ½À´Ï´Ù. ==== Á¤·Ä ==== ±âÁ¸¿¡´Â ±¸Á¶Ã¼ÀÇ sizeof() ¿¡ ÀÇÇÑ Á¤·ÄµÈ °ªÀÌ º¸Åë 4byte align·Î »ç¿ëµÇ¾úÀ¸³ª ÀÌ°ÍÀº ÀÌÁ¦ ±âº»°ªÀ¸·Î ¹ÏÀ»¼ö ¾ø½À´Ï´Ù. ÀÌÁ¦´Â º¸Åë 8byte align ÀÌ ±âº»°ªÀ¸·Î »ç¿ëµË´Ï´Ù. ¶§¹®¿¡ ¹Ýµå½Ã ÀǵµÀûÀ¸·Î alignÀ» ÇØ¾ß µÇ´Â °æ¿ì¶ó¸é ´ÙÀ½°ú °°ÀÌ ÀÛ¼ºµÇ¾î¾ß ÇÕ´Ï´Ù. (ÀÌ°ÍÀº »·ÇÑ ³»¿ëÀÌÁö¸¸ ±×°ÍÀ» À̾߱â ÇÏ·Á°í ÇÑ°ÍÀÌ ¾Æ´Ï°í ½ÅÁßÇÑ library °³¹ßÀÚ¶ó¸é ¸ðµç ±¸Á¶Ã¼´Â ¸í½ÃÀûÀ¸·Î align À» ÁöÁ¤ÇØÁà¾ß µÉ¼ö ÀÖ´Ù´Â °ÍÀ» ¸»ÇÕ´Ï´Ù.) {{{ #pragma pack(push,8) struct ts_my_struct { unsigned char b; unsigned short w; unsigned int d; unsigned long d; unsigned long long q; long double paragraph; } #pragma pack(pop) }}} ==== predefine À¸·Î 64bit ¸¦ °ËÃâ ==== °¢ architecture º° predefineÀÇ Á¾·ù°¡ ¸¹¾Æ¼­ °£´ÜÇÏ°Ô °ËÃâÇÒ¼ö ÀÖ´Â ³»¿ëÀº ¾Æ´ÏÁö¸¸ Á¦°¡ Áö±Ý±îÁö Æ÷ÆÃÇÑ architecture´Â ´ÙÀ½°ú °°ÀÌ ÇÏ¿© °ËÃâÇÏ¿´½À´Ï´Ù. »ç½Ç ÀÌ°ÍÀÌ ¸ðµÎ ¿Ïº®ÇÏ°Ô °ËÃâÇÑ´Ù°í ÇÒ¼ö´Â ¾ø½À´Ï´Ù. µé¾îº¸Áöµµ ¸øÇÑ architectureµµ ¸¹À¸´Ï±î.. {{{ #if defined(__x86_64__) || defined(__ia64__) || defined(_M_AMD64) || defined(_M_IA64) || defined(_WIN64) || defined(__alpha__) || defined(__s390__) /* ... */ /* ¿À~ ³ª 64bit ¿¡¼­ ÄÄÆÄÀÏ µÇ³×.. ¾îÇã ¿ä·¸°Ô ó¸®ÇÏÀÚ~ */ #endif }}} === ij½¬(cache) Á¶Á¤ === gcc »ç¿ëÀÚ¶ó¸é 64bit ¿¡¼­ º¸´Ù ³ôÀº ¼º´ÉÀ» À§ÇÏ¿© __builtin_expect((long)(m_expression),(long)(m_value)) ³»ÀåÇÔ¼öµµ Çѹø °ËÅäÇغ¸½Ã¸é ÁÁÀ»°Í °°½À´Ï´Ù. ÀÌ°ÍÀº Á¶°Ç½ÄÀÌ °ÅÀÇ ½ÇÇàµÇÁö ¾ÊÀ» È®·ü ¶Ç´Â ½ÇÇàµÉ È®·üÀ» Á¶Á¤ÇÔÀ¸·Î½á ÄÄÆÄÀÏ·¯·Î ÇÏ¿©±Ý Cache ÀÇ ÃÖÀû»ç¿ëÀ» À§ÇÑ ÃÖÀûÈ­°¡ °¡´ÉÇØÁöµµ·Ï À¯µµµÉ¼ö ÀÖ½À´Ï´Ù. 64bit ±â°è¾î Äڵ带 º¸½Ã¸é ÀÌ·¯ÇÑ Cache ¸¦ È¿°úÀûÀ¸·Î »ç¿ëÇÒ¼ö ÀÖµµ·Ï ÇÏ´Â ¹æ¹ýÀÌ Á¦°øµÇ±â ¶§¹®¿¡ À߸¸ »ç¿ëÇÏ¸é ¼º´ÉÀÌ ±Ø´ëÈ­ µÉ°ÍÀ¸·Î »ý°¢µË´Ï´Ù.