Uint_fast32_t là gì và tại sao nó nên được sử dụng thay vì int thông thường và uint32_t?


109

Vì vậy, lý do cho typedef: các kiểu dữ liệu nguyên thủy là để trừu tượng hóa biểu diễn cấp thấp và làm cho nó dễ hiểu hơn ( uint64_tthay vì long longkiểu, là 8 byte).

Tuy nhiên, có uint_fast32_tcái giống typedefnhư uint32_t. Sử dụng phiên bản "nhanh" có làm cho chương trình nhanh hơn không?


dài dài có thể không phải là 8 byte, có thể có độ dài dài bằng 1 byte (trong trường hợp CHAR_BIT ít nhất là 64) hoặc với 3738383 byte. còn uint64_t có thể là 1,2,4 hoặc 8 byte, CHAR_BIT phải là 64, 3, 16 hoặc 8 cho điều đó.
12431234123412341234123 15/12/16

Câu trả lời:


134
  • intcó thể nhỏ đến 16 bit trên một số nền tảng. Nó có thể không đủ cho ứng dụng của bạn.
  • uint32_tkhông được đảm bảo tồn tại. Nó là một tùy chọn typedefmà việc triển khai phải cung cấp iff nó có một loại số nguyên không dấu của chính xác 32-bit. Một số có byte 9 bit chẳng hạn, vì vậy chúng không có uint32_t.
  • uint_fast32_tnói rõ ý định của bạn: đó là loại có ít nhất 32 bit là loại tốt nhất theo quan điểm hiệu suất. uint_fast32_ttrên thực tế có thể dài 64 bit. Nó phụ thuộc vào việc thực hiện.

... có uint_fast32_tcùng một typedef như uint32_t...

Những gì bạn đang nhìn không phải là tiêu chuẩn. Đó là một triển khai cụ thể (BlackBerry). Vì vậy, bạn không thể suy ra từ đó uint_fast32_tluôn luôn giống như uint32_t.

Xem thêm:


35
Câu trả lời tốt. Để hoàn thiện, người ta có thể chỉ ra sự khác biệt uint_least32_t, điều này cũng giống như uint_fast32_tngoại trừ nó ủng hộ cửa hàng nhỏ hơn là tốc độ.
Damon

2
Tại sao số nguyên nhanh nhất có chiều rộng ít nhất là 32 bit lại lớn hơn 32 bit? Tôi luôn nghĩ nếu có ít bit hơn thì sẽ có ít bit hơn mà CPU phải làm việc, do đó nhanh hơn. Tôi còn thiếu gì ở đây?
Shane Hsu

12
@ShaneHsu: giả sử cpu 64 bit sẽ có mùa hè 64 bit, tính tổng các số 64 bit trong một chu kỳ. Không quan trọng nếu tất cả những gì bạn muốn làm là làm việc trên các số 32-bit, nó sẽ không nhanh hơn một chu kỳ. Bây giờ, mặc dù không phải như vậy trên x86 / amd64, các số nguyên 32-bit thậm chí có thể không được định địa chỉ. Trong trường hợp như vậy, việc xử lý chúng đòi hỏi các hoạt động bổ sung để trích xuất 32-bit từ các đơn vị căn chỉnh 64-bit. Xem thêm câu hỏi được liên kết. Chuẩn C ++ được viết để nó có thể hoạt động trên một máy có 37-bit từ ... vì vậy không có kiểu 32-bit nào ở đó cả.
Yakov Galka

42

Sự khác biệt nằm ở tính chính xác và tính khả dụng của chúng.

Tài liệu ở đây nói:

kiểu số nguyên không dấu với chiều rộng chính xác tương ứng là 8, 16, 32 và 64 bit ( chỉ được cung cấp nếu việc triển khai hỗ trợ trực tiếp kiểu ):

uint8_t
uint16_t
uint32_t
uint64_t

kiểu số nguyên không dấu nhanh nhất có chiều rộng ít nhất 8, 16, 32 và 64 bit tương ứng

uint_fast8_t
uint_fast16_t
uint_fast32_t
uint_fast64_t    

Vì vậy, sự khác biệt là khá rõ ràng đó uint32_tlà một kiểu có các bit chính xác 32 và việc triển khai chỉ nên cung cấp cho nó nếu nó có kiểu có chính xác 32 bit và sau đó nó có thể gõ kiểu đó là uint32_t. Điều này có nghĩa, uint32_tcó thể hoặc không có thể có sẵn .

Mặt khác, uint_fast32_tlà một kiểu có ít nhất 32 bit, điều đó cũng có nghĩa là, nếu một triển khai có thể gõ uint32_tnhư uint_fast32_t thể nó cung cấp uint32_t. Nếu nó không cung cấp uint32_t, thì uint_fast32_tcó thể là một typedef của bất kỳ loại nào có ít nhất 32bit.


3
Nhưng lý do nào làm cho ví dụ uint_fast32_t nhanh hơn uint32_t? Tại sao nó nhanh hơn?
Kẻ hủy diệt

2
@PravasiMeet: Không phải tất cả các số nguyên đều được truy cập theo cùng một cách. Một số dễ truy cập hơn những người khác. Dễ dàng hơn có nghĩa là ít tính toán hơn, trực tiếp hơn, dẫn đến truy cập nhanh hơn. Bây giờ uint32_tchính xác là 32-bit trên tất cả các hệ thống (nếu nó tồn tại), có thể không nhanh hơn so với hệ thống có 64-bit. uint_fast32_tmặt khác, ít nhất là 32 bit, thậm chí có thể là 64 bit.
Nawaz

10
@Destructor: Trên một số bộ xử lý, nếu một biến được lưu trữ trong thanh ghi dài hơn, trình biên dịch có thể phải thêm mã bổ sung để loại bỏ bất kỳ bit thừa nào. Ví dụ: nếu uint16_t x;được lưu trữ trong thanh ghi 32 bit trên ARM7-TDMI, mã x++;có thể cần được đánh giá là x=((x+1)<<16)>>16);. Trên các trình biên dịch cho nền tảng đó, uint_fast16_trất có thể sẽ được định nghĩa là đồng nghĩa với uint32_tđể tránh điều đó.
supercat

tại sao cũng [u]int_(fast|least)N_tkhông phải là tùy chọn? Chắc chắn không phải tất cả các kiến ​​trúc được yêu cầu bởi Tiêu chuẩn để hỗ trợ các kiểu nguyên thủy ít nhất là 64 bit? Tuy nhiên, từ ngữ cho stdint.hngụ ý rằng họ phải. Đối với tôi, có vẻ kỳ lạ là chúng tôi đã thực thi điều đó kể từ năm 1999, một số năm trước khi điện toán 64-bit trở thành xu hướng chủ đạo - không nói gì đến sự tụt hậu (trong nhiều trường hợp vẫn hiện tại) của các kiến ​​trúc nhúng. Đây dường như là một sự giám sát lớn đối với tôi.
underscore_d

1
@underscore_d: Chẳng hạn, không có lý do cụ thể nào mà Tiêu chuẩn không thể áp dụng cho việc triển khai PIC12 với 16 byte RAM dữ liệu và không gian cho 256 lệnh. Việc triển khai như vậy sẽ cần phải từ chối rất nhiều chương trình, nhưng điều đó không ngăn cản nó hoạt động theo kiểu xác định cho các chương trình mà nó có thể đáp ứng nhu cầu.
supercat

4

Khi #include inttypes.hở trong chương trình của mình, bạn có quyền truy cập vào một loạt các cách khác nhau để biểu diễn số nguyên.

Kiểu uint_fast * _t chỉ đơn giản xác định kiểu nhanh nhất để biểu diễn một số bit nhất định.

Hãy nghĩ về nó theo cách này: bạn xác định một kiểu biến shortvà sử dụng nó nhiều lần trong chương trình, điều này hoàn toàn hợp lệ. Tuy nhiên, hệ thống bạn đang làm việc có thể hoạt động nhanh hơn với các giá trị kiểu int. Bằng cách xác định một biến là kiểu uint_fast*t, máy tính chỉ cần chọn cách biểu diễn hiệu quả nhất mà nó có thể làm việc.

Nếu không có sự khác biệt giữa các biểu diễn này, thì hệ thống sẽ chọn bất kỳ cái nào nó muốn và sử dụng nó một cách nhất quán trong suốt.


9
Tại sao là inttypes.h mà không phải stdint.h? Có vẻ như inttypes.h chỉ chứa nhiều loại lông tơ hữu ích nhẹ khác nhau, cộng với stdint.h?
Lundin

@underscore_d Tôi biết sự khác biệt. Nhưng ai sử dụng stdio.h trong các chương trình chuyên nghiệp, bất kể lĩnh vực ứng dụng nào?
Lundin

@Lundin Tôi không biết họ là ai, hoặc liệu họ có tồn tại hay không! Tôi chỉ nghĩ rằng nó có thể hữu ích nếu cung cấp một liên kết giải thích về cái "lông tơ hữu ích nhẹ" đó là gì ;-) Có lẽ nó sẽ giúp mọi người nhận ra bạn đúng và họ không cần nó.
underscore_d

-1

Lưu ý rằng phiên bản nhanh có thể lớn hơn 32 bit. Trong khi int nhanh sẽ vừa khít trong một thanh ghi và được căn chỉnh và tương tự như vậy: nhưng, nó sẽ sử dụng nhiều bộ nhớ hơn. Nếu bạn có nhiều mảng lớn trong số này, chương trình của bạn sẽ chậm hơn do nhiều lần truy cập vào bộ nhớ cache và băng thông.

Tôi không nghĩ rằng CPUS hiện đại sẽ được hưởng lợi từ fast_int32, vì nói chung, dấu hiệu mở rộng từ 32 đến 64 bit có thể xảy ra trong quá trình tải và ý tưởng rằng có một định dạng số nguyên 'gốc' nhanh hơn đã lỗi thời.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.