
ç§ã®ããã°ã®å€ãäŒçµ±ãåéããŠãç§ã¯ç°¡åãªã¿ã¹ã¯ãåãããã®ä»£æ¿ãœãªã¥ãŒã·ã§ã³ã®é床ã«é·ããªã¹ããèæ ®ãããããã®ã¡ãªããã«æè¬ããŸãã
åçŽãªã¿ã¹ã¯ã¯æ¬¡ã®ãšããã§ãããã€ãã¹ããªãŒã ããããŒã¿ãèªã¿åããå€ãå¯å€ãããæ°ã§ãšã³ã³ãŒãããŸãã åã ã®ãã€ãããã·ã³ã¯ãŒããªã©ãèªã¿åããŸãã ã»ãšãã©ã®ããã»ããµãšå€ãã®ããã°ã©ãã³ã°èšèªã§çŽæ¥ãµããŒããããŠããŸãããå¯å€ãããé·ã§å ¥åºåããå Žåãéåžžã¯èªåã§ãœãªã¥ãŒã·ã§ã³ãå®è£ ããå¿ èŠããããŸãã
ç°¡åã«èãããŸãããããæå³ã§ã¯ããã§ãã åé¡ã®æåã®åå ã¯ããã®æäœãã³ãŒããã¯ãç©æ¥µçã«äœ¿çšããããšã§ã-ã¯ããã¡ã¢ãªãšI / Oã§ã¯ãªãèšç®ã«å¶éãããŸãã ãããã£ãŠãåã«æ©èœããã ãã§ãªããå¹æçãªå®è£ ãå¿ èŠã§ãã ãããŠãã®éçšã§ãI / Oãããã¡ãªã³ã°ããããã¡ãŒãšã³ãåŠçãC / C ++ã§å®çŸ©ããããããã·ããã®ãããããã¯ãããŸããŸãªããã»ããµã¢ãŒããã¯ãã£ãããã³ãããã·ããã®ä»ã®æ©èœãšã®ããåããçºçããŸãã
ãã®æçš¿ã§ã¯ãäž»ã«ãªãŒããŒãå®è£ ããããŸããŸãªæ¹æ³ã«çŠç¹ãåœãŠãŸãã å®éãããã§èª¬æãããã¹ãŠã®ææ³ã¯èšé²éšåã«ãåæ§ã«é©çšã§ããŸãããã¢ã«ãŽãªãºã ã®ããªãšãŒã·ã§ã³ã®æ°ã2åã«ãããã¯ãããŸããã ãããã¯ååã«ãããŸãã
èªç±åºŠ
ãå¯å€ãããæ°ã®èªã¿åããã¯ãã¿ã¹ã¯ã®èª¬æãäžååã§ãã ãããããã€ãã«ããã¯ããå€ãã®åãå ¥ãå¯èœãªæ¹æ³ãããããããã®ãã¹ãŠã«ç¬èªã®é·æãšçæããããŸããããã«ã€ããŠã¯åŸã§èª¬æããŸãã ãããŸã§ã®éããããã®éãã ããèŠãŠã¿ãŸãããã
ãŸãæåã«éèŠãªéžæãè¡ãå¿ èŠããããŸã-ãã£ãŒã«ãã¯ãå çMSBããŸãã¯ãå çLSBãã®åœ¢åŒã§ããã¯ãããŸãïŒãæäžäœãããã-æäžäœãããããã³ãæäžäœãããã-æäžäœãããïŒã ã€ãŸããå®è£ ããã
getbits
é¢æ°ãåŒã³åºããŠæ¬¡ã®ã³ãŒããå®è¡ãããš
a = getbits(4); b = getbits(3);
æ°ããéããããããã¹ããªãŒã ã®å Žåãåããã€ãããäž¡æ¹ã®å€ãåä¿¡ããããšäºæ³ãããŸããããã®ãã€ãã§ã©ã®ããã«é åºä»ããããŸããïŒ MSBãã¡ãŒã¹ãã®åœ¢åŒã§ããã¯ãããŠããå Žåããaãã¯MSBã§å§ãŸã4ããããå æãããbãã¯ãaããããäœãããã次ã®ã¹ããŒã ã«ã€ãªãããŸãã

ãã®ããã«ãããã«çªå·ãä»ããŸããLSBã¯0ã§ãMSBã«è¿ã¥ããšãå€ãå¢å ããŸãã å€ãã®ã³ã³ããã¹ãã§ã¯ããã®é åºãæšæºã§ãã LSB-firstã¯å察ã®ç¶æ³ã§ããæåã®ãã£ãŒã«ãã¯ããã0ãåãã次ã®ãã£ãŒã«ãã«ã¯å¢å ãããããçªå·ãå«ãŸããŸãã

äž¡æ¹ã®åœ¢åŒã¯ãäžè¬çãªãã¡ã€ã«åœ¢åŒã§äœ¿çšãããŸãã ããšãã°ãJPEGã¯ãããã¹ããªãŒã ã§MSBãã¡ãŒã¹ã圢åŒã®ããããããã³ã°ã䜿çšããDEFLATEïŒzipïŒã¯LSBãã¡ãŒã¹ãã䜿çšããŸãã
解決ããå¿ èŠããã次ã®è³ªåã¯ãå€ãæ°ãã€ãã«æ¡åŒµããããšãã«äœãèµ·ãããã§ãã 5ãããã§ãšã³ã³ãŒãããå¥ã®cå€ããããšããŸãã çµæãšããŠäœãåŸãããŸããïŒ ãã€ãã§ã¯ãªã32ããããŸãã¯64ãããã®ã¯ãŒãã§å€ãããã¯ããããšã宣èšããããšã«ãããåé¡ã®è§£æ±ºããããã«é ãããããšãã§ããŸãããæçµçã«ã¯äœããéžæããå¿ èŠããããŸãã ãããŠãããã§ç§ãã¡ã¯çªç¶å€ãã®ç°ãªãéžæè¢ã«çŽé¢ããŠããã®ã§ãç§ã¯äž»èŠãªç³è«è ã®ã¿ãæ€èšããŸãã
MSBãã¡ãŒã¹ãããããããã³ã°ã¯ãMSBããLSBãžã®ãcãããããã£ãŒã«ãã®å埩ãšããŠèªèãããäžåºŠã«1ããããã€æ¿å ¥ãããŸãã 1ãã€ããå ¥åãããã次ã®ãã€ãã«é²ã¿ãŸãã ããããã£ãŒã«ãcã«ã€ããŠãããã®èŠåã«åŸããšãã¹ããªãŒã ã®çµæãšããŠããããã¯æ¬¡ã®ã¹ããŒã ã«ãªããŸãã

ãããã®ã«ãŒã«ã«åŸããšãMSBãããã倧ããªæŽæ°ã«ããã¯ããŠããã°ãšã³ãã£ã¢ã³ã®é åºã§ä¿åããããšã§åŸãããã®ãšåã2ãã€ãã«ãªãããšã«æ³šæããŠãã ããã 代ããã«LSBãæåã®ãã€ãã«ããã4ã€ã®äžäœãããã2çªç®ã®ãã€ãã«ãªãããã«ãcããåå²ããããšã«ããå Žåãããã¯æ©èœããŸããã ãã®ãããªäžè²«ããããããããã³ã°ã«ãŒã«ããèªç¶ãªãã«ãŒã«ãšåŒã³ãŸãã
ãã¡ãããLSBãã¡ãŒã¹ãããããããã³ã°ã«ã¯ç¬èªã®èªç¶ãªèŠåããããŸãã ããã¯ãLSBããéå§ããŠããããããšã«æ°ããå€ãæ¿å ¥ããããšã§æ§æããããããè¡ããšãçµæãšããŠæ¬¡ã®ãããã¹ããªãŒã ãååŸãããŸãã

LSBãã¡ãŒã¹ãã®èªç¶ãããã³ã°ã¯ãLSBãã¡ãŒã¹ãã®å€§ããªæŽæ°ãžã®ãããã³ã°ãšåããã€ããæäŸãããªãã«ãšã³ãã£ã¢ã³ã®ãã€ãé ãç¶æããŸãã ããã«ãåçã«ã¯æãããªäžåšçšãããããŸããæ°ãã€ãã®ãcããã£ãŒã«ãã®è«ççã«å ±åœ¹ãããããã³ã°ã¯ããã®åçã§ã¯äžé£ç¶ã«èŠããŸãããMSBãã¡ãŒã¹ãã®ãããã³ã°ç»åã¯äºæ³ã©ããã§ãã ããããããã«ã¯åé¡ããããŸããMSBãã¡ãŒã¹ãã®ç»åã§ã¯ãããããå³ããå·Šã«å¢å ããé åºïŒæšæºïŒã§çªå·ä»ããããã€ããå·Šããå³ã«å¢å ããé åºã§çªå·ä»ãããŸãïŒãããæšæºã§ãïŒã
å·ŠåŽã®åãã€ãã«ããã0ïŒLSBïŒãæç»ããå³åŽã®ããã7ïŒMSBïŒãæç»ãããšãLSBãã¡ãŒã¹ãããããããã§äœãèµ·ãããã瀺ããŸãã

ãã®ããã«æç»ãããšãåè·¯ã¯äºæ³ã©ããã«ãªããŸãã ãã€ããæ°å€ãšèãããšãå³åŽã®MSBã®äœçœ®ã¯å¥åŠã«èŠããŸããã8ãããã®é åãšèãããšãããã»ã©å¥åŠã§ã¯ãªãããšãããããŸãïŒå®éã«ã¯ããããåäœã®I / Oãè¡ããšãã«ãããåŠçããŸãïŒã
å¶ç¶ã«ããäžéšã®ããã°ãšã³ãã£ã¢ã³ã¢ãŒããã¯ãã£ïŒIBM POWERãªã©ïŒã§ã¯ããããã«æ¬¡ã®ããã«çªå·ãä»ããããŠããŸã-ããã0ã¯MSBãããã31ïŒãŸãã¯63ïŒã¯LSBã§ãã ãã®ãããªãã·ã³ã§ããã0 = MSBã®MSBãã¡ãŒã¹ãããããããã³ã°ã¹ããŒã ãäœæããããã0ãMSBã«å¯Ÿå¿ããããã«ç¬èªã®ããããã£ãŒã«ãã«çªå·ãä»ãããšããŸã£ããåãã¹ããŒã ãåŸãããŸãïŒãã ããããã¯å°ãç°ãªãããšãæå³ããŸãïŒ ïŒ ãã®æšæºã¯ãããããšãã€ãã®é åºãäžè²«æ§ã®ãããã®ã«ããŸãïŒããã¯è¯ãããšã§ããïŒãããããkã 2 kã®å€ã«äžèŽããããšãã䟿å©ãªæšæºãå£ããŸãïŒå®å šã«è¯ããšã¯éããŸããïŒã
ãŸããããã0ãMSBã«ãªãããã«ãããã®çªå·ãä»ãçŽããšããèããè³ãççºãããå Žåã¯ããããã®çªå·ä»ããå€æŽããã«ãåæè ã«ãªããå·ŠåŽã«å¢å ãããã€ãã¢ãã¬ã¹ãæç»ã§ããŸãã ãŸãã¯ãã¢ãã¬ã¹ãå³ã«å¢ãããŸããããããã«ç°ãªãåéè ã«ãªããéã®é åºã§ãã€ãã¹ããªãŒã ãèšé²ããŸãã ãããã®ãªãã·ã§ã³ã®ãããããéžæãããšã次ã®ã¹ããŒã ãåŸãããŸãã

ããã¯ãã§ã«æ··ä¹±ãå§ããŠããããšãç解ããŠãããããã§åæ¢ããŸãããããã§äœãéèŠãªããšãèšããªããã°ãªããŸããïŒãã€ããåä¿¡ããæ¹æ³ã«é床ã«å·çããªãã§ãã ããã åã«èŠãç®ãè¯ããããšãã£ãŠããããªãã·ã§ã³ãä»ã®ãªãã·ã§ã³ãããåªããŠãããšæãããã®ã¯ç°¡åã§ããããã€ããå·Šããå³ã«ããã®äžã®ããããå³ããå·Šã«ååŸããåºæºã¯å®å šã«ä»»æã§ããå€ã ã
MSBãã¡ãŒã¹ããšLSBãã¡ãŒã¹ãã®åããã±ãŒãžã³ã°æšæºã«ã¯ããããé·æãšçæããããäžæ¹ããæ£ããããããäžæ¹ããééã£ãããšæå®ããããããã¢ããªã±ãŒã·ã§ã³ã®åéãç°ãªãããŒã«ãšèããæ¹ãã¯ããã«äŸ¿å©ã§ãã ãã€ããªãŒããŒãšãå€ããã€ããã¯ãŒãããŸãã¯ãã倧ããªãã®ã«ããã¯ããå¿ èŠæ§ã«ã€ããŠã¯ãããããããã³ã°æšæºã«æãèªç¶ãªé åºã䜿çšããããšã匷ããå§ãããŸããMSB-firstã¯åœç¶ãããã°ãšã³ãã£ã¢ã³ã®ãã€ãé ã«å¯Ÿå¿ããLSB -firstã¯ããªãã«ãšã³ãã£ã¢ã³ã®ãã€ãé ãšèªç¶ã«äžèŽããŸãã éã®é åºã§ãã€ãã¹ããªãŒã ãèšè¿°ããªãéãïŒä¿¡ããããªããããããŸããããããããè«ççãªçç±ããããŸãïŒã ãã®å Žåããªãã«ãšã³ãã£ã¢ã³ã«å¯Ÿå¿ããéé ã§MSBãã¡ãŒã¹ããååŸããããã°ãšã³ãã£ã¢ã³ã«å¯Ÿå¿ããéé ã§LSBãã¡ãŒã¹ããååŸããŸãã
ãèªç¶ãªãé åºãéžæããçç±ã¯ãããããç°ãªãå®è£ ã§ãã倧ããªèªç±ãäžããããã§ãã èªç¶ãªé åºã®ã¹ããªãŒã ã§ã¯ãå€ãã®ç°ãªããã³ãŒããŒïŒããã³ãšã³ã³ãŒããŒïŒã䜿çšã§ããŸãããããããã«ç¬èªã®ãã¬ãŒããªãïŒããã³ããŸããŸãªã±ãŒã¹ã§ã®å©ç¹ïŒããããŸãã ãäžèªç¶ãªã泚æã¯éåžžã1ã€ã®ç¹å®ã®å®è£ ã§é©çšãããä»ã®æ¹æ³ã§ãã³ãŒãããããšéåžžã«äžäŸ¿ã§ãã
æåã®getbits
ïŒãããæœåºïŒ
åé¡ãååãªéã§èª¬æããã®ã§ããœãªã¥ãŒã·ã§ã³ãå®è£ ã§ããŸãã ãããã¹ããªãŒã å šäœãé£ç¶ããŠïŒãã€ãã®é åã®ããã«ïŒã¡ã¢ãªå ã«ãããšä»®å®ãããšãç¹ã«åçŽãªããŒãžã§ã³ãå¯èœã«ãªããçŸåšã®ãšãããé åã®æåŸã«å°éãããªã©ã®äžå¿«ãªåé¡ãå®å šã«ç¡èŠããŸãã ç¡éã®ãµããããŸãããïŒ ïŒã©ã¡ããååã«å€§ãããããšããžã®åšãã«ãŒãããã£ã³ã°ããããŸããïŒ
ãã®å ŽåãçŽç²ã«æ©èœçãªããããæœåºãé¢æ°ã«åºã¥ããŠå®è£ ãè¡ãããšãã§ããŸãããã®é¢æ°ã§ã¯ãçºçããåé¡ãšããããçš®é¡ã®ãããèªã¿åãé¢æ°ã説æããŸãã LSBãã¡ãŒã¹ãããããããã¯ããããšããå§ããŸãããã
// buf[] integer little-endian, "width" // , "pos" (LSB= 0). uint64_t bit_extract_lsb(const uint8_t *buf, size_t pos, int width) { assert(width >= 0 && width <= 64 - 7); // 64- little-endian, , // "pos" ( "buf"). uint64_t bits = read64LE(&buf[pos / 8]); // , // . // LSB LSB . bits >>= pos % 8; // "width" , . return bits & ((1ull << width) - 1); } // , // - . const uint8_t *bitstream; // size_t bit_pos; // . uint64_t getbits_extract_lsb(int width) { // uint64_t result = bit_extract_lsb(bitstream, bit_pos, width); // bit_pos += width; return result; }
LSBãã¡ãŒã¹ããããã¹ããªãŒã ã¯ããªãã«ãšã³ãã£ã¢ã³ã®æ°ãå€ããšããäºå®ãå©çšããŸããã æåã«ãé¢å¿ã®ãããããã®ãããããå«ãæåã®ãã€ãããå§ãŸã64ã®é£æ¥ãããããã€ãåäœã§é 眮ããå¿ èŠãªæåã®ãããã®äžã«ããæ®ãã®äœåãª0-7ããããåãé€ãããã«å³ã«ã·ãããããã¹ã¯ãããçµæãè¿ããŸãåžæã®å¹ ã
pos
ã®å€ã«å¿ããŠããã®å³ãžã®ã·ããã«ã¯ããã«7ããããããå¯èœæ§ããããŸãã ãããã£ãŠã64ãããå šäœãèªã¿åããŸããããã®ã³ãŒãã§äžåºŠã«èªã¿åãããšãã§ããæ倧éã¯64-7 = 57ãããã§ãã
bitextract
ã
bitextract
ãç°¡åã«å®è£
getbits
ãŸãã ãããã¹ããªãŒã ã®çŸåšã®äœçœ®ïŒãããåäœïŒã远跡ããèªã¿åãåŸã«ã€ã³ã¯ãªã¡ã³ããå®è¡ããŸãã
MSBãã¡ãŒã¹ãã®å¯Ÿå¿ãããªãã·ã§ã³ã¯ãã³ãŒãã®ãã¢ã³ã¹ãã¬ãŒã·ã§ã³åŸã«èª¬æãã1ã€ã®åä»ãªåé¡ãé€ããŠãããªã䌌ãæ¹æ³ã§ååŸãããŸãã
// buf[] integer big-endian, "width" // , "pos" (MSB= 0). uint64_t bit_extract_msb(const uint8_t *buf, size_t pos, int width) { assert(width >= 1 && width <= 64 - 7); // 64- big-endian, , // "pos" ( "buf"). uint64_t bits = read64BE(&buf[pos / 8]); // , . // MSB MSB . bits <<= pos % 8; // "width" . return bits >> (64 - width); } uint64_t getbits_extract_msb(int width) { // uint64_t result = bit_extract_msb(bitstream, bit_pos, width); // bit_pos += width; return result; }
ãã®ã³ãŒãã¯åã®ã³ãŒããšåæ§ã«æ©èœããŸãïŒãã€ãã§é åããã64ã®é£ç¶ãããïŒä»åã¯ããã°ãšã³ãã£ã¢ã³ïŒãèªã¿åããå¿ èŠãªããããã£ãŒã«ãã®äžéšãMSB
bits
ã«æããããã«å·Šã·ãããå®è¡ã
bits
ïŒèª¿æŽããããã«å³ã·ãããè¡ãåã«ïŒ LSB
bits
ïŒã䜿çšããŠããããã£ãŒã«ãã®äžéš
getbits(3)
ã
getbits(3)
ãããå³ã«ã·ããããŠäžã®äžäœããããé 眮ããŠããããè¿ããŸããããã¯ã
getbits(3)
ãåŒã³åºããšãã«éåžž0ãã7ã®å€ã衚瀺ãããããšãæåŸ ããŠããããã§ã
å¢çã·ããã®å Žå
ããã§åé¡ã¯äœã§ããïŒ ãã®ããŒãžã§ã³ã®ã³ãŒãã§ã¯ã
width
ãŒãã«
width
ããšã¯ã§ããŸããã åé¡ã¯ã
width == 0
ãèš±å¯ãããšãæçµã·ããã64ãããå€ã64ãããå³ã«ã·ããããããšããããšã§ãããC / C ++ã§ã¯ããã¯æªå®çŸ©ã®åäœã§ãïŒ ãã®å Žåã0ã63ãã€ãã®ã·ãããå®è¡ã§ããŸãã
å Žåã«ãã£ãŠã¯ãC / C ++ã§ã¯ããã·ã³ãšã®äžäœäºææ§ã®ããã«è©³çŽ°ãæªå®çŸ©ã®ãŸãŸã«ãªããããçŸæç¹ã§ã¯èª°ãå¿é ããŠããŸããã ããç¥ãããäŸïŒç¬Šå·ä»ãæ°å€ã®è¡šçŸã«è¿œå ã®ã³ãŒãã䜿çšãããšããèŠä»¶ããªãã ã¢ãŒããã¯ãã£ã¯è¿œå ã®ã³ãŒããªãã§ååšããŸãããä»æ¥ã§ã¯ãã¹ãŠãåç©é€šã«ã®ã¿ä¿åãããŠããŸãã
æ®å¿µãªããããããã®ã±ãŒã¹ã¯ãããŸããã ã·ããéãç¯å²å€ã®å Žåãåºã䜿çšãããŠããããŸããŸãªCPUã¢ãŒããã¯ãã£ã§äœãèµ·ãããã次ã«ç€ºããŸãã
- 32ãããx86ããã³x86-64ã®å Žåãã·ããå€ã¯ã32ããã以äžã®ãªãã©ã³ãå¹ ã§ã¯mod 32ã64ããããªãã©ã³ãã§ã¯mod 64ãšããŠè§£éãããŸãã ã€ãŸããçµæãšããŠ64ãããå€ã64ã ãå³ã«ã·ãããããšã0ã«ããã·ãããšåãã«ãªããŸãã æäœã®æ¬ åŠïŒããŒãªãã¬ãŒã·ã§ã³ïŒã
- 32ãããARMïŒA32 / T32åœä»€ã»ããïŒã§ã¯ãã·ããå€ã¯mod 256ã«ãªããŸããçµæãšããŠ32ãããå€ã®32ïŒãŸãã¯64ïŒã®å³ã·ããã¯0ã«ãªãã255ã«å³ã·ããããŸããã256ã«å³ã·ãããããšå€ããã®ãŸãŸæ®ããŸãã ã
- 64ãããARMïŒA64 ISAïŒã§ã¯ã32ãããã·ããã®å Žåã¯mod 32ã64ãããã·ããã®å Žåã¯mod 64ïŒæ¬è³ªçã«x86-64ãšåãïŒã§ã·ããå€ãååŸãããŸãã
- RISC-Vãåãã«ãŒã«ã«åŸããŸãã32ãããã·ããã®è·é¢ã¯mod 32ã64ãããã·ããã®è·é¢ã¯mod 64ãšã¿ãªãããŸãã
- POWER / PowerPCã§ã¯ã32ãããã·ããã¯mod 64ã®ã·ããå€ãåãã64ãããã·ããã¯mod 128ã®ã·ããå€ãåããŸãã
ããã«æ··ä¹±ãããããã«ããããã®åœä»€ã»ããã®ã»ãšãã©ã«ã¯SIMDæ¡åŒµæ©èœããããæŽæ°SIMDåœä»€ã«ã¯éSIMDåœä»€ä»¥å€ã®ç°ãªããªãã·ããåäœããããŸãã èŠããã«ãããã¯äžè¬çãªãã©ãããã©ãŒã éã§ã¢ãŒããã¯ãã£ã®éããããå Žåã®1ã€ã§ãã ã»ãšãã©ã®äººã«ãšã£ãŠãPOWERãšRISC-Vã¯å°ãæ代é ãã«èŠãããããããŸããããããšãã°32ããããš64ãããã®ARMã¯çŸåšãäœåãã®ããã€ã¹ã«ã€ã³ã¹ããŒã«ãããŠããŸãã
ãããã£ãŠãã³ã³ãã€ã©ããã®å³ãžã®ã·ããã§è¡ãããšãã¹ãŠã-ã¿ãŒã²ããã¢ãŒããã¯ãã£ã«å¯Ÿå¿ããå³ãžã®ã·ããåœä»€ãäžãããšããŠãïŒãããŠéåžžã¯çºçããŸãïŒãã¢ãŒããã¯ãã£ããšã«ç°ãªãåäœãèŠãããŸãã ARM A64ããã³x86-64ã§ã¯ã64ãžã®ã·ããã®çµæã¯åºæ¬çã«äœãå®è¡ãããªãããã
getbits(0)
ã¯ïŒéåžžïŒãŒã以å€ã®å€ãè¿ããŸããããŒããè¿ãããããšãäºæ³ãããŸãã
ãªãããããããªã«éèŠãªã®ã§ããïŒ ãã¡ããã
getbits(0)
ã³ãŒãã¯èå³æ·±ã䜿çšäŸã§ã¯ãããŸããã ãã ããå€æ°xã«å¯ŸããŠ
getbits(x)
ãå®è¡ããå¿ èŠãããå ŽåããããŸããxã¯å Žåã«ãã£ãŠã¯ãŒãã«ãªãããšããããŸãã ãã®å Žåãã³ãŒããæ£åžžã«æ©èœããç¹å¥ãªã±ãŒã¹ã®ãã§ãã¯ãå¿ èŠãšããªãã®ã§ããã°çŽ æŽãããããšã§ãã
ãã®ã±ãŒã¹ãæ©èœããããå Žåã1ã€ã®ãªãã·ã§ã³ã¯æ瀺çã«
width == 0
ããã§ãã¯ãããããç¹å¥ãªæ¹æ³ã§åŠçããããšã§ãã å¥ã®ãªãã·ã§ã³ã¯ãå¹ ããŒãã§åäœããåå²ãªãã®åŒã䜿çšããããšã§ããããšãã°ã Jenne Colletã® FSEã䜿çšãã次ã®ã³ãŒãã§ãã
// "width" , width==0. return (bits >> 1) >> (63 - width);
ãã®ç¹å®ã®ã±ãŒã¹ã¯ãLSBãã¡ãŒã¹ããããã¹ããªãŒã ã®æ¹ãæ±ããããã§ãã ãããŠããããã«ã€ããŠèšåããã®ã§ããã¹ã¯ã䜿çšããæäœã«ã€ããŠè©±ããŸãããããã¹ã¯ã䜿çšããŠã
width
ããããåé¢ããŸããã
// "width" , . return bits & ((1ull << width) - 1);
åæ§ã®åœ¢åŒããããŸããããã¯ã3ãªãã©ã³ãããã³è£æ°ïŒAND-NOTïŒåœä»€ã䜿çšããã¢ãŒããã¯ãã£ã§ãããã«å®äŸ¡ã§ãã ãããã«ã¯ãå€ãã®RISC CPUãšBMI1ãåããx86ãå«ãŸããŸãã ã€ãŸãããã¹ãŠã®ãããåäœã®ãã¹ã¯ãååŸããå·Šã·ãããå®è¡ããŠäžéš
width
ãŒãã®
width
ãè¿œå ããŠããããã¹ãŠãè¿œå ã§ããŸãã
return bits & ~(~0ull << width);
x86ã«BMI1ã ãã§ãªãBMI2ã®ãµããŒããããå Žåãã³ã³ãã€ã©ãŒã«ãããæäŸããïŒãŸãã¯ã¢ã»ã³ãã©ãŒã䜿çšããïŒæ¹æ³ã
BZHI
ã§ããã°ããã®å Žåã®ããã«ç¹å¥ã«äœæããã
BZHI
åœä»€ã䜿çšã§ããŸãã å Žåã«ãã£ãŠã¯æãŸãããã1ã€ã®ãªãã·ã§ã³ã¯ãã³ãŒããåçŽåããå°ããªããããããã«ãã¯ã¢ããããŒãã«ãåçŽã«æºåããããšã§ãã
return bits & width_to_mask_table[width];
2ã€ã®æŽæ°æŒç®ã®çµæãæ ŒçŽããã«ãã¯ã¢ããããŒãã«ãæºåããã®ã¯ããšãã§ããªãã¢ã¯ã·ã§ã³ã®ããã«èŠããŸããç¹ã«ãããŒãããããŒãã«èŠçŽ ã®ã¢ãã¬ã¹ã®èšç®ã«ã¯éåžžãã·ãããšå ç®ã®äž¡æ¹ãå«ãŸããŸããããŒãã«ïŒ -ãããããã®çæ°ã«ã¯ç¬èªã®æ¹æ³ããããŸãïŒå¿ èŠãªã¢ãã¬ã¹ã®èšç®ã¯ãããšãã°x86ããã³ARMãã·ã³äžã®1ã€ã®ããŒãåœä»€ã§ã¡ã¢ãªã¢ã¯ã»ã¹ã®äžéšãšããŠå®è¡ã§ããããã ãã®ã·ãããšè¿œå ã¯ã¢ãã¬ã¹çæãŠãããïŒAGUïŒã§èšç®ãããŸãCPUãžã®ããŒããã€ãã©ã€ã³ã®äžéšãšããŠãæŽæ°æŒç®ããã³ã·ããåœä»€ã§ã¯ãããŸããã ã€ãŸãã2ã€ã®æŽæ°ALUåœä»€ã1ã€ã®æŽæ°ããŒãåœä»€ã«çœ®ãæãããšããçŽæã«åãã決å®ã¯ãç°ãªããªãã¬ãŒãã£ã³ã°ãŠãããéã§è² è·ã®ãã©ã³ã¹ãæ¹åãããããã¢ã¯ãã£ããããI / Oã䜿çšããã³ãŒãã®å€§å¹ ãªé«éåã«ã€ãªãããŸãã
ãã1ã€ã®èå³æ·±ãç¹æ§ã¯ããã¹ã¯ã«ãã¯ã¢ããããŒãã«ã䜿çšããLSBãã¡ãŒã¹ãããŒãžã§ã³ããå€æ°ã«ãã£ãŠ1ã€ã®ã·ãããå®è¡ããããšã§ãïŒæ¢ã«èªã¿åãããããããã·ããããããïŒã å€ãã®ïŒå€ãã®å ŽåãäºçŽ°ãªïŒïŒçç±ã§ãå€ãã®ãã€ã¯ãã¢ãŒããã¯ãã£ã§ã¯ãå€æ°ã«ããæŽæ°ã®ã·ããã¯ã³ã³ãã€ã«æéã®å®æ°å€ã«ããã·ãããããé«äŸ¡ã§ãããããããã¯éèŠã§ãã ããšãã°ãCell PPU / Xbox 360 Xenonã¯ã12ãµã€ã¯ã«ãšããéåžžã«é·ãæéããã»ããµã³ã¢ã®é床ãäœäžãããå¯å€è·é¢ã·ããã§æªåãé«ããå®æçãªã·ããããã€ãã©ã€ã³ã«çµã¿èŸŒãŸãã2ãµã€ã¯ã«ã§å®è¡ãããŸããã å€ãã®Intel x86ãã€ã¯ãã¢ãŒããã¯ãã£ã§ã¯ããåŸæ¥ã®ãx86å€æ°ã·ããïŒ
SHR reg, cl
ãªã©ïŒã¯ãã³ã³ãã€ã«æå®æ°ã«ããã·ããããã3åé«äŸ¡ã§ãã
ããã¯ãMSBãã¡ãŒã¹ãããªã¢ã³ããæåŠãããã1ã€ã®çç±ã®ããã§ããäžèšã®ãªãã·ã§ã³ã¯ããããæœåºæäœã«å¯ŸããŠ2ã€ãŸãã¯3ã€ã®ã·ãããå®è¡ããŸãã ãããã1ã€ã®ã·ãããã€ãŸãéåžžã®ã·ããã®ä»£ããã«åŸªç°ã·ããã䜿çšããŠæäœã«æ»ãããšãã§ããããªãã¯ã®ãããããããŸãã
// buf[] integer big-endian, "width" // , "pos" (MSB= 0). uint64_t bit_extract_rot(const uint8_t *buf, size_t pos, int width) { assert(width >= 0 && width <= 64 - 7); // 64- big-endian, , // "pos" ( "buf"). uint64_t bits = read64BE(&buf[pos >> 3]); // , LSB. bits = rotate_left64(bits, (pos & 7) + width); // "width" . // ( , // - LSB-first.) return bits & width_to_mask_table[width]; }
ããã§ãå·ŠããŒããŒã·ã§ã³ïŒCã³ã³ãã€ã©ã§ã®æé©ãªäœ¿çšæ¹æ³ãç解ããå¿ èŠããããŸãïŒã¯ãæåã«å ã®å·Šã·ããã®äœæ¥ãè¡ãã次ã«äœåãªãå¹ ãããããå転ããŠãããããã£ãŒã«ããå€ã®æäžäœãããããæäžäœãããã«å転ãããŸã, , LSB-first.
ãããã¯ããç§ã¯8ã§é€ç®ãå³ã«3ã·ãããç¡ç¬Šå·äœçœ®ã®mod-8ããã€ããªAND 7ã§æžãå§ããŸããããããã¯åçã®çœ®æã§ããããã®ãããªåœ¢åŒãå®éã®ã³ãŒãã§èŠãããšãã§ããã®ã§ãããã«è¿œå ããããšã«ããŸããã
ãã®å転ãã¹ã¯æäœã䜿çšããŠãRAD Game Toolsã§Cell PPUãšXbox 360ã®ããããèªã¿åããŸãããããã¯ããã®ã³ã¢ã§å¯å€è·é¢ã·ãããã²ã©ãããã§ããããã®ããŒãžã§ã³ã«ãåé¡ããªãããšã«æ³šæããŠãã ãã
width == 0
ãå¯äžã®åé¡ã¯ãã»ãšãã©ã®ã¢ãŒããã¯ãã£ã«ååšããïŒãããŠè¿ éã«å®è¡ãããïŒããŒããŒã·ã§ã³åœä»€ãžã®äŸåæ§ã§ãããéåžžãCã³ãŒããããããã«ã¢ã¯ã»ã¹ããã®ã¯äžäŸ¿ã§ãã
ãããã·ãããšãã¹ãã³ã°ãå®è¡ããããŸããŸãªæ¹æ³ã«ã€ããŠã¯æ¢ã«èª¬æããŸããããå°æ¥ã¯ããããåç §ããŸãããããããããI / Oã®å®çšçãªããžãã¯ã¯ãŸã 瀺ããŠããŸããïŒããããæœåºãã圢åŒã¯ãç¶æ ãèããã«æŠå¿µã説æããã®ã«äŸ¿å©ãªè¯ãåºçºç¹ã§ãããå®éã®ã³ãŒãã§ã¯ãç¹ã«ããã䜿çšããªãã§ããããããã¹ããªãŒã å šäœãã¡ã¢ãªå ã«ãããéåžžã®å®è¡ããã»ã¹ã§ãããã¡ã®æåŸãŸã§ç°¡åã«èªã¿åããããšãåæãšããŠããŸãïŒ
ããã§ãç§ãã¡ã¯äž»ãªã¿ã¹ã¯ã決å®ãããã¹ã¯ã®ã·ãããšäœ¿çšãå®è¡ããããŸããŸãªæ¹æ³ãæ€èšãããã¹ã¯ã®åºæã®åé¡ãæããã«ããŸãããç§ãéžæããããããæœåºã圢åŒã¯ãç¶æ ã®ãªãããªããã£ãã«åºã¥ããŠããŸããããã¯ãã«ãŒãäžå€åŒã䜿çšããªãã£ããããæåãã䟿å©ã§ããã
次ã«ãééããã»ãšãã©ã®ããããªãŒããŒã§äœ¿çšãããç¶æ ã®ã¹ã¿ã€ã«ã«é²ã¿ãŸãïŒæãå®äŸ¡ã§ããããšãå€æããããïŒããŸããã¢ããªã·ãã¯ãªæ©èœ
getbits
ãããããå€ãã®éšåã«åå²ãããæ©èœã«ç§»è¡ããŸããããããæåããå§ããŸãããã
ãªãã·ã§ã³1ïŒå ¥åã1ãã€ããã€èªã¿èŸŒã
ããšã¯ã¹ãã©ã¯ã¿ãŒããªãŒããŒã¯ããããã¹ããªãŒã å šäœãäºåã«ã¡ã¢ãªå ã«ããããšãåæãšããŠããŸããããã¯åžžã«å¯èœãŸãã¯æãŸãããšã¯éããŸããããã1ã€ã®æ¥µç«¯ãªã±ãŒã¹ãã€ãŸãããããªãŒããŒã調ã¹ãŠãå¿ èŠãªãšãã«ã ãè¿œå ã®ãããã1ã€ãã€èŠæ±ããŸãã
äžè¬ã«ãã¹ããŒããã«ãªãã·ã§ã³ã¯äžåºŠã«æ°ãã€ãã®å ¥åãåãåããéšåçã«åŠçãããããã€ãã®ãã€ããæã¡ãŸãããã®ããŒã¿ãå€æ°ã«ä¿åããå¿ èŠããããããããããããããã¡ãŒããšåŒã³ãŸãã
// // , . uint64_t bitbuf = 0; // int bitcount = 0; //
å ¥ååŠçäžããã®ãããã¡ãçµäºãããšåžžã«æ°ãããããããã®ãããã¡ã«æžã蟌ãããå¯èœã§ããã°ãã®ãããã¡ããããããèªã¿åããŸãã
èŠåŽãã
getbits
ã«ãäžåºŠã«1ãã€ããã€èªã¿åãæåã®å®è£ ãäœæããŸããããä»åã¯MSBãã¡ãŒã¹ãããå§ããŸãã
// : "bitbuf" "bitcount" , // MSB ; "bitbuf" - 0. uint64_t getbits1_msb(int count) { assert(count >= 1 && count <= 57); // , // Big endian; , // . while (bitcount < count) { bitbuf |= (uint64_t)getbyte() << (56 - bitcount); bitcount += 8; } // ; // "count" "bitbuf" . uint64_t result = bitbuf >> (64 - count); // bitbuf <<= count; bitcount -= count; return result; }
åãšåæ§ã«ã
count
åã®éšåã§èª¬æããããã«ãçµæã®ããããååŸããæ¹æ³ãå€æŽããããšã«ãããâ¥1 ã®èŠä»¶ãåãé€ãããšãã§ããŸããæåŸã«ããã«ã€ããŠèšåããŸããã¢ã«ãŽãªãºã ã®ããŒãžã§ã³ã衚瀺ãããã³ã«ã以åã®ããªãšãŒã·ã§ã³ãèªåçã«é©çšãããããšã«æ³šæããŠãã ããã
ããã§ã®ã¢ã€ãã¢ã¯éåžžã«åçŽã§ãããŸããèŠæ±ãããã«æºããã®ã«ååãªãããããããã¡ã«ãããã©ããã確èªããŸããããã§ãªãå Žåã¯ãååãªéã«ãªããŸã§ãäœåãªãã€ãã1ã€ãã€æžã蟌ã¿ãŸããããã¯
getbyte()
ãçæ³çã«ã¯ãããçš®ã®ãããã¡ãªã³ã°ãããI / Oã¡ã«ããºã ã䜿çšããããšãæå³ããŸããããã¯ãã¯ãªãã£ã«ã«ãã¹äžã®ãã€ã³ã¿ãŒã®éåç §ãšã€ã³ã¯ãªã¡ã³ãã«åçŽã«ãªããŸãããããé¿ããããšãã§ãããªãã°ãããã¯ãããŸããé¢æ°åŒã³åºããŸãã¯é«äŸ¡ãªãã®ã§ããå¿ èŠããããŸããäžåºŠã«8ããããæ¿å ¥ããããã1åã®åŒã³åºãã§æ倧57ããããã«ãŠã³ãã§ããŸããããã¯ãäœã倱ãå±éºãåããã«ãããã¡ãè£å ã§ããæ倧ãããæ°ã§ãã
ãã®åŸ
count
ããããã¡ããäžäœããããååŸããããããã·ããããŸããããã«ä¿åãããäžå€åŒã¯ãã«ãŠã³ããããŠããªãæåã®ããããMSBãããã¡ãŒã«ä¿åãããããšã§ãã
ãŸãããã®ããã»ã¹ã3ã€ã®å°ããªæäœã«äŸ¿å©ã«åå²ãããŠããããšã«ã泚æããŠãã ããããããã®æäœããè£å ãããããŒã¯ããããã³ãæ¶è²»ããšåŒã³ãŸãã ãè£å ããã§ãŒãºã§ã¯ããããã¡ãŒã«æå°æ°ã®ããããååšããããšãä¿èšŒãããŸãã ãã¹ãã£ã³ãã¯ããããã¡å ã®æ¬¡ã®æ°ããããç Žæ£ããã«è¿ãããæ¶è²»ãã¯ããããèŠãã«ããããåé€ããŸãããããã¯ãã¹ãŠåå¥ã«åœ¹ç«ã¡ãŸããããããã¹ãŠã©ã®ããã«æ§æãããŠãããã瀺ãããã«ãLSBãã¡ãŒã¹ãã¢ã«ãŽãªãºã ã«çžåœãããã®ãããå°ããªéšåã«åããŠç€ºããŸãã
// : "bitbuf" "bitcount" , // LSB ; "bitbuf" - 0. void refill1_lsb(int count) { assert(count >= 0 && count <= 57); // . while (bitcount < count) { bitbuf |= (uint64_t)getbyte() << bitcount; bitcount += 8; } } uint64_t peekbits1_lsb(int count) { assert(bit_count >= count); return bitbuf & ((1ull << count) - 1); } void consume1_lsb(int count) { assert(bit_count >= count); bitbuf >>= count; bitcount -= count; } uint64_t getbits1_lsb(int count) { refill1_lsb(count); uint64_t result = peekbits1_lsb(count); consume1_lsb(count); return result; }
getbits
ããã3ã€ã®å°ããªããªããã£ããçµã¿åãããŠèšé²ããããšã¯ãåžžã«æé©ãšã¯éããŸãããããšãã°ãMSBãã¡ãŒã¹ãããããããã¡ã«å転æ¹æ³ã䜿çšããå Žåãå転ããã§ãŒãº
peekbits
ãšã«åå²ããå¿ èŠããã
consume
ãŸã; æé©ãªå®è£ ã§ã¯ãäœæ¥ãããã2ã€ã®ãã§ãŒãºã«åå²ãããŸãããã ãããããã®3ã€ã®ãã§ãŒãºãã¹ãŠãåå¥ã®ã¹ããããšããŠãã¹ã¿ãŒãããšãããããããŸããŸãªæ¹æ³ã§äžç·ã«äœ¿çšã§ãããããã³ãŒãããããã®åå¥ã®ã¹ãããã«åå²ããããšã¯äŸç¶ãšããŠæçšã§ãã
楜ãã¿ã«ããŠ
ãã®ãããªæãéèŠãªå€æã¯ãããã€ãã®ãã³ãŒãæäœã®è£å ååŽã§ããç°¡åãªããã¡ãã®äŸããå§ããŸãããã以åã«ååŸãã3ãããã®ãã£ãŒã«ããã«ãŠã³ãããããšããŸãã
a = getbits(4); b = getbits(3); c = getbits(5);
å Žå
getbits
ãäžèšã®ããã«å®è£ ããããã®ã³ãŒãã¯3åïŒè£å ããã»ã¹ããããã圌èªèº«ïŒãŸã§å®äºããããšã確èªããŸããããããããã¯æãã§ããäžåºŠã«4 + 3 + 5 = 12ããããèªã¿åãããšãäºåã«ããã£ãŠããããããã¹ãŠåæã«ååŸã§ããŸãã
refill(4+3+5); a = getbits_no_refill(4); b = getbits_no_refill(3); c = getbits_no_refill(5);
ããã§ã
getbits_no_refill
-å¥ã®ãªãã·ã§ã³getbitsãè¡ã
peekbits
ãš
consume
ååãè£å ããããšãªããæå³ããããã«ããããããããŠãå¥ã ã®åŒã³åºãéã®ãªãã£ãŒãžãµã€ã¯ã«ãåãé€ããšã
getbits
ã³ã³ãã€ã©ãŒã«ãã£ãŠæé©åãããåçŽãªæŽæ°ã³ãŒããããããŸããã§ãããèšãæããã°ãåºå®é·ã®ã±ãŒã¹ã¯äœã³ã¹ãã§ããããšãã°ã次ã®ããã«ãå®éã«æ¶è²»ãããããæ°ãããããªãå Žåã¯ããã«èå³æ·±ããã®ã«ãªããŸãã
temp = getbits(5); if (temp < 28) result = temp; else result = 28 + (temp - 28)*16 + getbits(4);
ããã¯ã0ã27ã®å€ã5ãããã§éä¿¡ããã28ã91ã®å€ã9ãããã§éä¿¡ãããåçŽãªå¯å€é·ã³ãŒãã§ãããã€ã³ãã¯ããã®å Žåãå°æ¥æ¶è²»ãããããæ°ãäºåã«ããããªãããšã§ãããã ãã9ããã以äžããããšãããã£ãŠãããããè£å ã1åã ãçºçããããšã確èªã§ããŸãã
refill(9); temp = getbits_no_refill(5); if (temp < 28) result = temp; else result = 28 + (temp - 28)*16 + getbits_no_refill(4);
å®éãå¿ èŠã«å¿ããŠããã¹ãŠã®å®è¡ãã¹ã§ããã«æäœãäžæããŠãäž¡æ¹ã®å®è¡ãã¹ãäžåºŠã ãïŒ
consume
ïŒããããæ¶è²»ããããã«ããããšãã§ããŸããããšãã°ãMSBãã¡ãŒã¹ãããããããã¡ã䜿çšããå Žåããã®å°ããªãã³ãŒãã次ã®ããã«èšè¿°ã§ããŸãã
refill(9); temp = peekbits(5); if (temp < 28) { result = temp; consume(5); } else { // "" "" , // ! ! result = getbits_no_refill(9) - 28*16 + 28; }
ãã®ãããªãã€ã¯ããã¥ãŒãã³ã°ã¯ãéåžžã«ããžãŒãªãµã€ã¯ã«ã®å¢çãè¶ ããŠåŒ·ãæšå¥šãããããšã¯ãããŸããããåè¿°ããããã«ããããã®ãã³ãŒããµã€ã¯ã«ã®äžéšã¯éåžžã«è² è·ãé«ãããã®å Žåãããã€ãã®åœä»€ãç°ãªãå Žæã«ä¿åãããšæ·±å»ãªå©åŸãåŸãããŸããå¯å€é·ã³ãŒãïŒããšãã°ããããã³ã³ãŒãïŒããã³ãŒãããããã®ç¹ã«éèŠãªææ³ã¯ãç¹å®ã®ãããæ°ãå èªã¿ãããã®çµæã«åºã¥ããŠããŒãã«ãæ€çŽ¢ããããšã§ããããŒãã«èŠçŽ ã¯ããã³ãŒããããæåãäœã§ããããæ¶è²»ããå¿ èŠã®ããæåæ°ïŒã€ãŸããæåã«å®éã«å±ããã¹ãã£ã³ããããããæ°ïŒã瀺ããŸããããããã£ãšãããŸããããã³ããªãŒã®åã¹ãããããã§ãã¯ããŠãäžåºŠã«1ã€ãŸãã¯2ãããã®ã³ãŒããèªã¿åããããé«éã§ãïŒæ®å¿µãªããããã®æ¹æ³ã¯å€ãã®æç§æžããã®ä»ã®å ¥éããã¹ãã§æäŸãããŠããŸãïŒã
ããããåé¡ããããŸããå èªã¿ããŠæ¶è²»ãããããæ°ã決å®ããæè¡ã¯åå匷åã§ãããã«ãŒã«ãå€æŽãã
getbits
ã ãã§ããäžèšã®å®è£ ã¯ã絶察ã«å¿ èŠãªå Žåã«ã®ã¿äœåãªãã€ããèªã¿åãããšããŸãããã ããå¯å€é·ã®ã³ãŒããªãŒããŒã®å€æŽäŸã¯åžžã«è£å ããããããæçµçã«5ãããããæ¶è²»ããªãå Žåã§ãããããã¡ãŒã«ã¯å°ãªããšã9ããããå«ãŸããŸããè£å ãè¡ãããå Žæã«ãã£ãŠã¯ãããŒã¿ã¹ããªãŒã èªäœã®çµäºåŸã«èªã¿åããè¡ãããå ŽåããããŸããå èªã¿ã®
æ¹æ³ã«æ £ããŸãããå€æŽãããã³ãŒããªãŒããŒã¯ããã®å¿ èŠæ§ã確èªãããåã§ãã£ãŠããè¿œå ã®å ¥åãåãåãå§ããŸãããã®ã¢ãããŒãã«ã¯å€ãã®å©ç¹ããããŸããããã¬ãŒããªãã¯ããããã¹ããªãŒã ã®è«ççãªçµããã®å€åŽã匷å¶çã«èªã¿èŸŒããããšã§ããããã¯ããã®ãããªå Žåã®æ£ããåŠçã確å®ã«è¡ãå¿ èŠãããããšãæå³ããŸããã¯ããã¯ã©ãã·ã¥ã®åå ã«ãªã£ãããã¹ããªãŒã ã®å€éšã§èªã¿åã£ããããããšã¯ãããŸãããããããããã«å ããŠãå ¥åãããã¡ãªã³ã°ãŸãã¯ã¯ãããã³ã°ã¬ã€ã€ãŒã®åäœåçãæå³ããŸãã
å èªã¿ãããå ŽåããããåŠçããæ¹æ³ãå¿ èŠã§ããäž»ãªãªãã·ã§ã³ã¯æ¬¡ã®ãšããã§ãã
- - , , - . , .
- , ,
getbits
, , ( - , ); , - ( ). - , lookahead , , . , 64- , , - 8- (, - ). , , .
- , -, , , . , lookahead , , . , C
ungetc
,ungetc
, . -.
ç§ã¯ããªããæ °ããŸãã-ãããã®ãªãã·ã§ã³ã¯ãã¹ãŠå®è£ ãé£ãããäžéšã¯ä»ã®ãªãã·ã§ã³ãããå°é£ã§ããæåŸã«äœããæ¿å ¥ããŠåé¡ãåãé€ãã®ãæãç°¡åãªæ¹æ³ã§ããå€éšãã¬ãŒãã³ã°ã¬ã€ã€ãŒã®ç¶æ³ãåŠçããããšãè¯ã解決çã§ãããI / Oãããã¡ãªã³ã°ã³ã³ãããŒã«å šäœãäœãçŽããŠæ°ãã€ãã®èªã¿åãããã£ã³ã»ã«ããã®ã¯æ¬åœã«ã²ã©ãã§ããããããããªãã³ã°ãå¶åŸ¡ã§ããªãå Žåãåã«è¯ã解決çã¯ãããŸãããéå»ã«ãç§ã¯ãã®æèã§åœ¹ç«ã€äŸ¿å©ãªãã¯ããã¯ã«é¢ããæçš¿ãæžããŸãããå®è£ ã«ãã£ãŠã¯ãããšãã°æ¬¡ã®ããã«èšå®ããããšã§åé¡ãåé¿ã§ããŸãã
bitcount
åå«ããæåŸã®ãã€ããæ¿å ¥ããçŽåŸã®å·šå€§ãªå€ãããããäžè¬çãªã±ãŒã¹ã§ã¯ãå èªã¿ãå®è£ ããå Žåã¯ãããçšåºŠã®åŽåãè²»ããå¿ èŠããããŸããããããéåžžãåã€ããšã¯ããã ãã®äŸ¡å€ãããã®ã§ãããã¯ã«ãŒã¬ããã²ãŒã ã§ã¯ãããŸããã
ãªãã·ã§ã³2ïŒç§ãã¡ã¯æ¬åœã«äžåºŠã«64ããããã«ãŠã³ãããå¿ èŠããããŸã
åã«èª¬æãããã¹ãŠã®ã¡ãœããã¯ããã€ãåäœã§ã®äœæ¥ãé¿ããããã«ããŸããŸãªããªãã¯ã䜿çšããŸããæœåºããããªãŒããŒã¯ãå®å šãª64ããããèªã¿åãããšããå§ãŸããŸãããçŸåšã®ãã€ãã®ãã§ã«æ¶è²»ãããéšåãç Žæ£ããããã«7ããžã·ã§ã³ã·ããããå¿ èŠããããŸããäžèšã®äŸ
getbits1
ã§ã¯ãããããããã¡ãŒã«äžåºŠã«1ãã€ããæ¿å ¥ããŸãããããã¡ã«ãã§ã«57ããããããããæ°ãããã€ãçšã®ã¹ããŒã¹ããªãå ŽåïŒçµæã¯ãããã¡ã®å¹ ããã倧ãã65ãããã§ããããïŒãããã¯ã¡ãœããã§ãµããŒããããæ倧å¹
getbits1
ã§ãã 57ãããã¯ããªãæçšãªéã§ããã32ããããã©ãããã©ãŒã ã§äœæ¥ããå Žåãåæ§ã®ããžãã¯ãã³ããŒã¯25ãããïŒ32-7ïŒã«ãªããããã¯ããªãå°ãªãéã§ãããå€ãã®å Žåååã§ã¯ãããŸããã
幞ããªããšã«ãå šå¹ ãå¿ èŠãªå Žåã¯ããããå®è£ ããæ¹æ³ããããŸãïŒMSBãã¡ãŒã¹ãã®å転ããã³ããããããã¡ãŒãã¹ã¯ã䜿çšããææ³ãšåæ§ã«ãRADã§ãããåŠã³ãŸããïŒããã®æ®µéã§ãMSBãã¡ãŒã¹ããšLSBãã¡ãŒã¹ãã®ã¡ãœããã®é¢ä¿ã¯ãã§ã«ç解ããŠãããšæãã®ã§ã1ã€ã®ãªãã·ã§ã³ã®ãœãªã¥ãŒã·ã§ã³ã®ã¿ã瀺ããŸãã LSBãã¡ãŒã¹ããéžæããŸãããïŒ
// : "bitbuf" "bitcount" , // LSB ; 1 <= bitcount <= 64 uint64_t bitbuf = 0; // int bitcount = 0; // uint64_t lookahead = 0; // 64 bool have_lookahead = false; // , ! void initialize() { bitbuf = get_uint64LE(); bitcount = 64; have_lookahead = false; } void ensure_lookahead() { // lookahead, // . if (!have_lookahead) { lookahead = get_uint64LE(); have_lookahead = true; } } uint64_t peekbits2_lsb(int count) { assert(bitcount >= 1); assert(count >= 0 && count <= 64); if (count <= bitcount) { // buf return bitbuf & width_to_mask_table[count]; } else { ensure_lookahead(); // bitbuf lookahead // ( lookahead buf) uint64_t next_bits = bitbuf; next_bits |= lookahead << bitcount; return next_bits & width_to_mask_table[count]; } } void consume2_lsb(int count) { assert(bitcount >= 1); assert(count >= 0 && count <= 64); if (count < bitcount) { // - buf // bitbuf >>= count; bitcount -= count; } else { // buf ensure_lookahead(); // lookahead int lookahead_consumed = count - bitcount; bitbuf = lookahead >> lookahead_consumed; bitcount = 64 - lookahead_consumed; have_lookahead = false; } assert(bitcount >= 1); } uint64_t getbits2_lsb(int count) { uint64_t result = peekbits2_lsb(count); consume2_lsb(count); return result; }
ãã®ãããªã¢ãããŒãã¯ãäžèšã§æ€èšããã¢ãããŒããããå°ãè€éã§ãããäžå€åŒãæ£ããæ©èœããããã«æ瀺çãªåæåã¹ããããå¿ èŠã§ãããŸãã以åã®ããŒãžã§ã³ãšã¯ç°ãªããããã€ãã®è¿œå ãã©ã³ãã䜿çšãããããPCãªã©ã®æ確ãªãã€ãã©ã€ã³ãæã€ãã·ã³ã«ã¯ããŸãé©ããŠããŸãããããã«ãç§ã¯ãããåã³äœ¿çšããŠããããšã«æ³šæããŠãã ãã
width_to_mask_table
ãããã¯ãã¢ã³ã¹ãã¬ãŒã·ã§ã³ã®ããã ãã§ã¯ãããŸããïŒäžããããå¹ ã®ãã¹ã¯ãèšç®ããããã«åå䜿çšããç®è¡åŒã¯
width
ãäžè¬çãª64ãããã¢ãŒããã¯ãã£ã§æå¹ãªå šéé0-64ã§æ©èœããŸããIBM POWERãããŠãããã¯ãã¡ãããèš±å¯ãããªãäžæ確ãªæ¯ãèãã®ææŠãç¡èŠããå Žåã«ã®ã¿æ©èœããŸãã
åºæ¬çãªèãæ¹ã¯éåžžã«åçŽã§ãã1ã€ã®ãããã¡ãŒã ãã§ã¯ãªãã2ã€ã®å€ã远跡ããŸããæåŸã«èªã¿åããã64ãããå€ããæ®ãã®ãããæ°ãããã£ãŠãããã
peekbits
ãããããååã§ãªãå Žåãå ¥åã¹ããªãŒã ãã次ã®64ãããå€ãååŸãïŒå€éšå®è£ ã䜿çš
get_uint64LE()
ïŒãæ¬ èœããŠããããããååŸããŸããåæ§ã«ãããã
consume
ãæ¶è²»ããåŸãçŸåšã®å ¥åãããã¡ã«ããããæ®ã£ãŠãããã©ããã確èªã
width
ãŸããããã§ãªãå Žåã¯ãå èªã¿å€ãããããã«åãæ¿ããŠïŒæ¶è²»ãããå€ã«ã·ããããïŒããã©ã°
have_lookahead
ãã¯ãªã¢ããŠãåã®å èªã¿å€ãåã«ããããããã¡ã®å 容ã«ãªã£ãããšã瀺ããŸãã
æå¹ãªç¯å²å€ã®ãªãã»ããããªãããšãä¿èšŒããããã«ããã®ã³ãŒãã«ã¯ãã©ã³ããååšããŸãïŒæªå®çŸ©ã®åäœãåŒãèµ·ãããŸãïŒãããšãã°ããããã¡ã«ãããããããã©ã
peekbits
ã
count <= bitcount
ãèªèããããã«ã©ã®ããã«ãã§ãã¯ãããã調ã¹ãŸãããã
consume
䜿çšã
count < bitcount
ãŸããããã¯å¶ç¶ã§ã¯ãããŸããïŒã®èšç®
next_bits
ã«
peekbits
ã¯ã«ããå³ã·ãããå«ãŸã
bitcount
ãŸããããã¯
bitcount
<
count
â€64 ã®ãã¹ã§ã®ã¿çºçããããã
bitcount < 64
å®å šã§ããããšãæå³ããŸãã
consume
ç¶æ³ãé転ããŠããïŒç§ãã¡ã¯ã·ãããè¡ããŸã
lookahead_consumed = count - bitcount
ããããã¯ãå²ãæ¡ä»¶ã¯ã
lookahead_consumed
â¥0ãä¿èšŒããŸããéæ¹åã§ã¯ã
count
64
bitcount
以äžã1 以äžãªã®ã§ã
lookahead_consumed
â€64-1 =63ãã€ãŸããKnuthã®èšèãèšãæãããšããäžèšã®ã³ãŒãã®ãã°ã«æ³šæããŠãã ãããç§ã¯ãããæ£ãã蚌æãããããã¹ãããªãã£ããã
ããããã£ãŒã«ãã®å¹ ãåºãããšã«å ããŠããã®ææ³ã«ã¯ãã1ã€ã®å©ç¹ããããŸããåžžã«äžåºŠã«å®å šãª64ãããuintãèªã¿åãããšã«æ³šæããŠãã ãããäžèšã®ãªãã·ã§ã³1ã¯äžåºŠã«ãã€ããèªã¿åããŸãããåå é»ãµã€ã¯ã«ãå¿ èŠã§ãã以äžã§èª¬æããããŸããŸãªéåå²ãªãã·ã§ã³ã¯ãé«éã®éæŽåèªã¿åãããµããŒãããããã«ã¿ãŒã²ããããã»ããµã«æé»çã«äŸåããŸããããã¯ã1ã€ã®ãµã€ãºãšäžå®ã®ã¢ã©ã€ã¡ã³ããèªã¿åãããšã§éç«ã£ãŠããå¯äžã®ããŒãžã§ã³ã§ãããã®ãããããšãã°å€ãã®å€ãRISCããã»ããµãªã©ãé«éã®éã¢ã©ã€ã¡ã³ãèªã¿åãããµããŒãããªãã¿ãŒã²ããã·ã¹ãã ã«ãšã£ãŠããé åçã§ãã
ãã€ãã®ããã«ãç§ãèŠããªãä»ã®ããªãšãŒã·ã§ã³ããããããããŸããããšãã°ãã¡ã¢ãªã«å®å šã«ãã³ãŒãããããŒã¿ãããå ŽåãããŒã«ãã©ã°ãå°ç¡ãã«ããçç±ã¯ãããŸãã
have_lookahead
ãçŸåšã®å èªã¿èªãžã®ãã€ã³ã¿ãä¿åããçŸåšã®å èªã¿èªãæ¶è²»ããããšãã®ãã€ã³ã¿ãã€ã³ã¯ãªã¡ã³ãã§ããŸãã
ãªãã·ã§ã³3ïŒãããæœåºã«æ»ã
åã®éšåããæœåºããå ã®ããããªãŒããŒã¯éåžžã«é«äŸ¡ã§ããããã ããå ¥åã¹ããªãŒã å šäœãåæã«ã¡ã¢ãªå ã«ãããšããèŠä»¶ã«æºè¶³ããŠããå Žåã¯ããããrefill / peek / consumerãã¿ãŒã³ã§ã©ããããŠæçšãªãã®ãååŸã§ããŸãããŸã å èªã¿ã®ããïŒãããã£ãŠã察å¿ããå°é£ãçããïŒå°ãã®èªè ãããŸãããããã¯äººçã§ããããã§ã¯ãããšãã°MSBãåã³äœ¿çšããŸãã
const uint8_t *bitptr; // uint64_t bitbuf = 0; // 64 int bitpos = 0; // void refill3_msb() { assert(bitpos <= 64); // bitptr += bitpos >> 3; // (Refill) bitbuf = read64BE(bitptr); // , // ( ; , // .) bitpos &= 7; } uint64_t peekbits3_msb(int count) { assert(bitpos + count <= 64); assert(count >= 1 && count <= 64 - 7); // uint64_t remaining = bitbuf << bitpos; // "count" return remaining >> (64 - count); } void consume3_msb(int count) { bitpos += count; }
ä»å
getbits
ã¯ããªãã£ã«/ããŒã¯/æ¶è²»ã®åŒã³åºãããæ§ç¯ããããã®ãåé€ããŸãããããã¯ããã1ã€ã®ç解ãã¹ããã¿ãŒã³ã§ããããã§ãã
ããã¯éåžžã«è¯ããªãã·ã§ã³ã§ããããªãã£ã«ããšãããŒã¯ã/ãæ¶è²»ãã®å¥ã ã®éšåã«ããããæœåºããããžãã¯ãç Žããšããããã®åã ã®ããŒã¹ãã©ãã»ã©å°ããç解ããããããæããã«ãªããŸãããããã«ãåå²ã¯å®å šã«ãããŸããïŒãã®ã¡ãœããã¯ãéæŽå64ãããããã°ãšã³ãã£ã¢ã³èªã¿åãå€ãååšããéåžžã«å®äŸ¡ã§ããããšãæåŸ ããŠããŸãïŒããã¯ãäžè¬çãªx86ããã³ARMã¢ãŒããã¯ãã£ã®åé¡ã§ã¯ãããŸããïŒãããã«ãçŸå®çãªå®è£ ã®ããã«ã¯ããããã¡ã®ãšã³ãã±ãŒã¹åŠçãè¿œå ããå¿ èŠããããŸãããå èªã¿ãã«é¢ããã»ã¯ã·ã§ã³ã®èª¬æãåç §ããŠãã ããã
ãªãã·ã§ã³4ïŒå¥ã®å èªã¿ã¿ã€ã
次ã«ãåå²ããã«å¥ã®å èªã¿ãªãã·ã§ã³ãå®è£ ããŸããããç§ã®ç¥ãéãããã®ãªãã·ã§ã³ã¯ã¯ã©ãŒã±ã³ã§äœæ¥äžã«ååã®ãã£ãŒã«ãºã»ãã«ãŒã ãšç§ãRADã®å©ããåããŠçºèŠããŸããïŒæŽæ°ïŒã€ã³ãã³ã¡ã³ãã§ææããããã«ãäž»ãªã¢ã€ãã¢ã¯ã¯ã©ãŒã±ã³ã®ãªãªãŒã¹ã®ããªãåã«Xpackã®ãšãªãã¯ã»ãã¬ãŒãºã«ãã£ãŠäœ¿çšãããŸãããç§ã¯ç¥ããŸããã§ããç§ãããã£ãŒã«ãºãšæããŸãããããã¯ããã®ã¢ã€ãã¢ã¯ç¢ºãã«é ã®äžã§ç§ãã¡ã«æ¥ãŠåããŠã§ã¯ãªããããããç§ãã¡ã®ããŒãžã§ã³ã¯èå³æ·±ãæ©èœãæã£ãŠããããšãæå³ããŠããŸã- ãã§è©³çŽ°ãåç §ããŠãã ãããç§ã®å¿çïŒãã¹ãŠã®ããããªãŒããŒã«ã¯åå²ããããŸãããïŒãªãã£ã«ãªã©ã§ãããã¡ã®çµããã®ãã§ãã¯ãç¡èŠãããšåå²ããŸããïŒããã®ãªãã·ã§ã³ã«ã¯ããã€ãã®èå³æ·±ãããããã£ããããŸãïŒå¿ èŠãªç¥èããªãããããããã®ããã€ãã«ã€ããŠã¯åŸã§èª¬æããŸãïŒããã®çµã¿åããã§ã¯ãç§ã¯ä»ã®ã©ãã«ãäŒã£ãããšããããŸãããä»ã®èª°ããç§ãã¡ã®åã«ãããªããã³ã¡ã³ãã§ç§ã«ç¥ãããŠãã ããããããŠç§ã¯ééããªãèè ã«èšåããŸãïŒãããã£ãŠãããã§ã¯LSBãã¡ãŒã¹ãã«æ»ããŸããããã¯ããã¹ãŠã®ããªããŒã«é¢ä¿ãªããLSBãã¡ãŒã¹ã/ MSBãã¡ãŒã¹ãããã®ã¬ãã«ã§äº€æå¯èœã§ããããšã瀺ãããã§ãã
const uint8_t *bitptr; // buf uint64_t bitbuf = 0; // int bitcount = 0; // void refill4_lsb() { // // . bitbuf |= read64LE(bitptr) << bitcount; // bitptr += (63 - bitcount) >> 3; // bitcount |= 56; // now bitcount is in [56,63] } uint64_t peekbits4_lsb(int count) { assert(count >= 0 && count <= 56); assert(count <= bitcount); return bitbuf & ((1ull << count) - 1); } void consume4_lsb(int count) { assert(count <= bitcount); bitbuf >>= count; bitcount -= count; }
ããŒã¯ãšã³ã³ã·ã¥ãŒã ã®æ®µéã¯ãã§ã«èŠãŠããŸããããä»åã¯äœããã®çç±ã§æ倧蚱容ãããå¹ ã1ã€æžå°ãã56ãããã«ãªããŸããã
çç±ã¯è£å 段éã§ããããã®åäœã¯ä»¥åã«èŠããã®ãšãããã«ç°ãªããŸãã 64ãããã®ãªãã«ãšã³ãã£ã¢ã³ãèªã¿åããããããçŸåšã®ããããããã¡ãŒã®æäžéšã«äžèŽããããã«ã·ããããããšã¯æããã§ãããã ãã
bitptr
/ã䜿çšããæäœã«
bitcount
ã¯èª¬æãå¿ èŠã§ãã
ããå§ããæ¹ãç°¡å
bitcount
ã§ããå ã»ã©èŠããªãã·ã§ã³ã§ã¯ããããã¡ãè£å ããåŸãéåžž57ããããã64ãããã«ãªããŸããããã ãããã®ããŒãžã§ã³ã¯ã56ã63ãããããããã¡ãŒã«æ ŒçŽããããšãç®çãšããŠããŸãïŒããããã«ãŠã³ã¿ãŒã®å¶éã1ã€æžã£ãçç±ã§ãïŒããããããªãã§ããïŒæŽæ°ã®ãã€ããæ¿å ¥ãããšãè£å æ
bitcount
ã«8ã®åæ°ã ãå¢å ããŸããããã¯ã
bitcount & 7
ïŒäžäœ3ãããïŒãå€æŽãããªãããšãæå³ããŸãããããŠããããã¡ã®[56.63]ããããç®æããŠãªãã£ã«ãè¡ããšãåäžã®ãã€ããªORæŒç®ã§æŽæ°ããããããæ°ãèšç®ã§ããŸãã
ããã¯æ¬¡ã®è³ªåã«ã€ãªãããŸãïŒãã€ã³ã¿ãŒãã·ããããã«ã¯äœãã€ãå¿ èŠã§ããïŒãœãŒã¹ã®å€ãèŠãŠã¿ãŸããã
bitcount
ïŒ
- 56â€â€63ã®å Žå
bitcount
ããã§ã«ã¿ãŒã²ããééå ã«ããã次ã®ãã€ãã«ç§»åããå¿ èŠã¯ãããŸããã - 48â€â€55ã®å Žå
bitcount
ãæ£ç¢ºã«1ãã€ããè¿œå ããŸãïŒbit_ptr
åãéã ã移åããå¿ èŠããããŸãïŒã - 40â€â€47ã®å Žå
bitcount
ãæ£ç¢ºã«2ãã€ããè¿œå ããŸãã
ãªã©ãªã©ãããã¯
(63 - bitcount) >> 3
ãã«è¿œå ãããã€ãã§æ©èœããŸã
bitptr
ããªãŒããŒ
ãããã®å Žå
bitbuf
ã
bitcount
ORæŒç®ãæ°åå®è¡ã§ããŸãããã ãããããçºçãããšãåãå€ã«ORãé©çšãããã³ã«çµæãå€æŽãããŸããããããã£ãŠãåŸã§æ¶è²»æ©èœã®å³ãžã®ã·ããã®ããã«ããããããäœã移åãããšãããã¹ãŠã¯ãããã§ããŸããããŸãããŽãã®å¯èœæ§ã«ã€ããŠå¿é ããå¿ èŠã¯ãããŸããã
ãã¡ãããããã¯é¢çœãã§ããããã®ããŒãžã§ã³ã®ç¹å¥ãªç¹ã¯äœã§ããïŒäžèšã®ãªãã·ã§ã³3ãªã©ã®ä»£ããã«ããã€äœ¿çšããå¿ èŠããããŸããïŒ
1ã€ã®ç°¡åãªçç±ããããŸãããã®ãªãã·ã§ã³ã§ã¯ãããŒãããã¢ãã¬ã¹
refill
ã¯çŸåšã®å€ã«äŸåããŸããã
bitcount
ãå®éã次ã®ããŠã³ããŒãã¢ãã¬ã¹ã¯ãååã®è£å ãå®äºããçŽåŸã«èªèãããŸãããã®ããããªéãã¯ã䞊å€ããå®è¡ãè¡ãããã»ããµã«ãšã£ãŠéåžžã«å€§ããªå©ç¹ã§ããæŽæ°ãå«ãæäœã®äžã§ãL1ãã£ãã·ã¥ã§ãããããå Žåã§ããèªã¿èŸŒã¿æäœã¯å€§ããªé 延ïŒéåžžã¯çŽ3ã5ãµã€ã¯ã«ãã»ãšãã©ã®æŽæ°æäœã¯1ãµã€ã¯ã«ããããŸãïŒã«ãã£ãŠç¹åŸŽä»ããã
bitcount
ããµã€ã¯ã«ã®å埩ã®çµäºæã®æ£ç¢ºãªå€ã¯é ãããããšãããã£ãŠããŸãïŒäžã§ç€ºããå¯å€é·ã®ç°¡åãªã³ãŒããåç §ããŠãã ããïŒã
ããŠã³ããŒãã¢ãã¬ã¹ãç¬ç«ããŠããå Žå
bitcount
ãããã¯ãåã®ãªãã£ã«ãå®äºããçŽåŸã«æœåšçã«ããŒãã³ãã³ããéä¿¡ã§ããããšãæå³ããŸããããŒãã®ãã€ãé ãã¿ãŒã²ããISAãšäžèŽããªãå ŽåïŒããšãã°ããªãã«ãšã³ãã£ã¢ã³CPUã§MSBãã¡ãŒã¹ãããããããã¡ãŒã䜿çšããå ŽåïŒãå€ã®å¯èœãªãã€ãé åã§ããŠã³ããŒããå®äºããååãªæéããããŸããåã®å€ã«äŸåããå¯äžã®ãã©ã¡ãŒã¿ãŒ
bitcount
ã¯ã·ãããã€ãŸããéåžž1ãµã€ã¯ã«ãããéåžžã®ALUæäœã§ãã
ç°¡åã«ãŸãšãããšããã®ããªãè€éãªè©°ãæ¿ãã®ããŒãžã§ã³ã¯å¥åŠã«èŠããŸãããåœä»€ã¬ãã«ã§ã®äžŠåæ§ã®æè»ãªå¢å ãæäŸããŸããåœæã®ææ°ããŒãžã§ã³ã®Kraken-Huffmanãã³ãŒããŒã§2016幎ã«ãã¹ããããšããããã¹ã¯ãããPCã§ã®é床ã®å¢å ã¯çŽ10ïŒ ã§ããïŒäžèšã®åå²ãªãã®ãªãã£ã«ã«æ¯ã¹ãŠïŒã