uint_fast32_t คืออะไรและเหตุใดจึงควรใช้แทน int ปกติและ uint32_t


110

ดังนั้นเหตุผลสำหรับtypedef: ประเภทข้อมูลดั้งเดิมของ ed คือการแสดงนามธรรมระดับต่ำและทำให้เข้าใจง่ายขึ้น ( uint64_tแทนที่จะเป็นlong longประเภทซึ่งมีขนาด 8 ไบต์)

อย่างไรก็ตามมีuint_fast32_tซึ่งมีเดียวกันเป็นtypedef uint32_tการใช้เวอร์ชัน "เร็ว" จะทำให้โปรแกรมเร็วขึ้นหรือไม่?


long long อาจไม่ใช่ 8 ไบต์เป็นไปได้ที่จะมี long long โดยมี 1 ไบต์ (ในกรณีที่ CHAR_BIT อย่างน้อย 64) หรือ 3738383 ไบต์ uint64_t สามารถเป็น 1,2,4 หรือ 8 ไบต์ CHAR_BIT ต้องเป็น 64, 3, 16 หรือ 8 สำหรับสิ่งนั้น
12431234123412341234123

คำตอบ:


135
  • intอาจมีขนาดเล็กถึง 16 บิตในบางแพลตฟอร์ม อาจไม่เพียงพอสำหรับการสมัครของคุณ
  • uint32_tไม่รับประกันว่าจะมีอยู่จริง เป็นทางเลือกtypedefที่การใช้งานจะต้องระบุ iff โดยมีประเภทจำนวนเต็ม 32 บิตที่ไม่ได้ลงชื่อ บางรุ่นมีขนาด 9 บิตดังนั้นจึงไม่มีไฟล์uint32_t.
  • uint_fast32_tระบุเจตนาของคุณอย่างชัดเจน: เป็นประเภทอย่างน้อย 32 บิตซึ่งดีที่สุดจากมุมมองด้านประสิทธิภาพ uint_fast32_tอาจมีความยาว 64 บิต มันขึ้นอยู่กับการนำไปใช้งาน

... uint_fast32_tซึ่งมี typedef เหมือนกับuint32_t...

สิ่งที่คุณกำลังมองหาไม่ใช่มาตรฐาน เป็นการใช้งานเฉพาะ (BlackBerry) คุณจึงไม่สามารถอนุมานจากตรงนั้นได้ว่าuint_fast32_tจะเหมือนกับเสมอuint32_tไป

ดูสิ่งนี้ด้วย:


36
คำตอบที่ดี. เพื่อความสมบูรณ์เราอาจชี้ให้เห็นถึงความแตกต่างuint_least32_tเช่นกันซึ่งก็เหมือนกับuint_fast32_tยกเว้นว่าจะชอบร้านค้าขนาดเล็กมากกว่าความเร็ว
Damon

2
เหตุใดจำนวนเต็มที่เร็วที่สุดที่มีความกว้างอย่างน้อย 32 บิตจึงมีขนาดใหญ่กว่า 32 บิต ฉันคิดเสมอว่าถ้ามีบิตน้อย CPU ก็จะต้องทำงานน้อยลงจึงเร็วขึ้น ฉันขาดอะไรไปที่นี่?
Shane Hsu

12
@ ShaneHsu: พูดว่า CPU 64 บิตจะมีฤดูร้อน 64 บิตซึ่งรวมตัวเลข 64 บิตในหนึ่งรอบ ไม่สำคัญว่าสิ่งที่คุณต้องการจะทำคือการทำงานกับตัวเลข 32 บิตมันจะไม่เร็วกว่าหนึ่งรอบ ตอนนี้แม้ว่าจะไม่เป็นเช่นนั้นบน x86 / amd64 แต่จำนวนเต็ม 32 บิตอาจไม่สามารถระบุแอดเดรสได้ ในกรณีเช่นนี้ต้องใช้ตัวดำเนินการเพิ่มเติมเพื่อดึงข้อมูล 32 บิตออกจากหน่วยที่จัดแนว 64 บิต ดูคำถามที่เชื่อมโยงด้วย มาตรฐาน C ++ ถูกเขียนขึ้นเพื่อให้สามารถทำงานบนเครื่องที่มีคำ 37 บิต ... ดังนั้นจึงไม่มีประเภท 32 บิตเลย
Yakov Galka

42

ความแตกต่างอยู่ที่ความแน่นอนและความพร้อมใช้งาน

docนี่พูดว่า:

ชนิดจำนวนเต็มไม่ได้ลงนามที่มีความกว้างตรง 8, 16, 32 และ 64 บิตตามลำดับ ( ให้เฉพาะถ้าการดำเนินการสนับสนุนโดยตรงชนิด ):

uint8_t
uint16_t
uint32_t
uint64_t

และ

ประเภทจำนวนเต็มไม่ได้ลงนามที่ไม่ได้ลงนามที่เร็วที่สุดโดยมีความกว้างอย่างน้อย 8, 16, 32 และ 64 บิตตามลำดับ

uint_fast8_t
uint_fast16_t
uint_fast32_t
uint_fast64_t    

ดังนั้นความแตกต่างสวยมากชัดเจนว่าuint32_tเป็นชนิดที่มีว่า 32บิตและการดำเนินการควรให้มันแต่ถ้ามันมีประเภทที่มีตรง 32 บิตแล้วก็สามารถ typedef uint32_tประเภทว่า วิธีนี้uint32_tอาจจะหรืออาจจะไม่สามารถใช้ได้

ในทางกลับกันuint_fast32_tเป็นประเภทที่มีอย่างน้อย 32 บิตซึ่งหมายความว่าหากการใช้งานอาจพิมพ์ดีฟuint32_tราวกับuint_fast32_t ว่ามีuint32_tจะให้หากไม่มีให้แสดงuint32_tว่าuint_fast32_tอาจเป็น typedef ประเภทใดก็ได้ที่มี32บิตเป็นอย่างน้อย


3
แต่อะไรคือสาเหตุที่ทำให้เช่น uint_fast32_t เร็วกว่า uint32_t? ทำไมถึงเร็วกว่า?
Destructor

2
@PravasiMeet: ไม่ใช่จำนวนเต็มทั้งหมดที่เข้าถึงได้ในลักษณะเดียวกัน บางคนเข้าถึงได้ง่ายกว่าคนอื่น ๆ ง่ายกว่าหมายถึงการคำนวณน้อยกว่าตรงกว่าซึ่งส่งผลให้เข้าถึงได้เร็วขึ้น ตอนนี้uint32_tเป็น 32 บิตในทุกระบบ (ถ้ามี) ซึ่งอาจไม่เร็วกว่าเมื่อเทียบกับระบบ 64 บิต uint_fast32_tในทางกลับกันอย่างน้อย 32 บิตอาจเป็น 64 บิตก็ได้
Nawaz

10
@Destructor: ในโปรเซสเซอร์บางตัวหากตัวแปรถูกเก็บไว้ในรีจิสเตอร์ที่ยาวกว่าคอมไพเลอร์อาจต้องเพิ่มโค้ดพิเศษเพื่อตัดบิตพิเศษออกไป ตัวอย่างเช่นหากuint16_t x;ถูกเก็บไว้ในรีจิสเตอร์ 32 บิตบน ARM7-TDMI โค้ดx++;อาจต้องได้รับการประเมินเป็นx=((x+1)<<16)>>16);ไฟล์. บนคอมไพเลอร์สำหรับแพลตฟอร์มuint_fast16_tนั้นส่วนใหญ่จะถูกกำหนดให้มีความหมายเหมือนกันuint32_tเพื่อหลีกเลี่ยงสิ่งนั้น
supercat

ทำไมถึง[u]int_(fast|least)N_tไม่เลือก? แน่นอนว่ามาตรฐานไม่จำเป็นต้องใช้สถาปัตยกรรมทั้งหมดเพื่อรองรับประเภทดั้งเดิมอย่างน้อย 64 บิต? แต่ถ้อยคำที่stdint.hบ่งบอกเป็นนัยว่าพวกเขาต้อง ดูเหมือนเป็นเรื่องแปลกสำหรับฉันที่เราบังคับใช้มาตั้งแต่ปี 2542 หลายปีก่อนที่คอมพิวเตอร์ 64 บิตจะกลายเป็นกระแสหลักโดยไม่ต้องพูดถึงความล้าหลังของสถาปัตยกรรมฝังตัว (ในหลายกรณีในปัจจุบัน) นี่ดูเหมือนเป็นการกำกับดูแลที่ยิ่งใหญ่สำหรับฉัน
underscore_d

1
@underscore_d: ไม่มีเหตุผลใด ๆ เช่นมาตรฐานไม่สามารถใช้กับการใช้งาน PIC12 ที่มีแรมข้อมูล 16 ไบต์และพื้นที่สำหรับ 256 คำสั่ง การนำไปใช้งานดังกล่าวจำเป็นต้องปฏิเสธโปรแกรมจำนวนมาก แต่ก็ไม่ควรป้องกันไม่ให้มีพฤติกรรมตามที่กำหนดไว้สำหรับโปรแกรมที่สามารถตอบสนองความต้องการได้
supercat

4

เมื่อคุณ#include inttypes.hอยู่ในโปรแกรมคุณจะสามารถเข้าถึงวิธีต่างๆมากมายในการแทนค่าจำนวนเต็ม

ประเภท uint_fast * _t จะกำหนดประเภทที่เร็วที่สุดสำหรับการแสดงจำนวนบิตที่กำหนด

ลองคิดดู: คุณกำหนดตัวแปรประเภทshortและใช้หลายครั้งในโปรแกรมซึ่งใช้ได้โดยสิ้นเชิง intอย่างไรก็ตามระบบที่คุณกำลังทำงานในการทำงานได้รวดเร็วยิ่งขึ้นอาจมีค่าประเภท โดยการกำหนดตัวแปรเป็นประเภทuint_fast*tคอมพิวเตอร์จะเลือกการแสดงที่มีประสิทธิภาพสูงสุดที่สามารถใช้งานได้

หากไม่มีความแตกต่างระหว่างการแสดงเหล่านี้ระบบจะเลือกสิ่งที่ต้องการและใช้อย่างสม่ำเสมอตลอดไป


9
ทำไมต้องเป็น inttypes.h และไม่ใช่ stdint.h? ดูเหมือนว่า inttypes.h จะมีเฉพาะปุยที่มีประโยชน์เล็กน้อยเท่านั้นรวมถึง stdint.h?
Lundin

@underscore_d ฉันรู้ความแตกต่าง แต่ใครใช้ stdio.h ในโปรแกรมระดับมืออาชีพไม่ว่าจะใช้งานด้านใด
Lundin

@ ลุนดินฉันไม่รู้ว่าพวกเขาเป็นใครหรือว่ามีอยู่จริง! ฉันแค่คิดว่ามันอาจมีประโยชน์ในการจัดเตรียมลิงก์ที่อธิบายรายละเอียดว่า "ปุยที่มีประโยชน์เล็กน้อย" คืออะไร ;-) บางทีมันอาจจะช่วยให้คนอื่นรู้ว่าคุณพูดถูกและพวกเขาไม่ต้องการมัน
underscore_d

-1

โปรดทราบว่าเวอร์ชันที่รวดเร็วอาจมีขนาดใหญ่กว่า 32 บิต ในขณะที่ int ที่รวดเร็วจะพอดีกับรีจิสเตอร์และอยู่ในแนวเดียวกัน แต่จะใช้หน่วยความจำมากขึ้น หากคุณมีอาร์เรย์ขนาดใหญ่เหล่านี้โปรแกรมของคุณจะทำงานช้าลงเนื่องจากจำนวนแคชหน่วยความจำและแบนด์วิดท์มากขึ้น

ฉันไม่คิดว่า CPUS สมัยใหม่จะได้รับประโยชน์จาก fast_int32 เนื่องจากโดยทั่วไปแล้วเครื่องหมายที่ขยาย 32 ถึง 64 บิตสามารถเกิดขึ้นได้ในระหว่างคำสั่งโหลดและความคิดที่ว่ามีรูปแบบจำนวนเต็ม 'เนทีฟ' ที่เร็วกว่านั้นล้าสมัย

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.