Apa itu uint_fast32_t dan mengapa harus digunakan sebagai pengganti int biasa dan uint32_t?

110

Jadi alasan untuk typedef: tipe data primitif adalah untuk mengabstraksi representasi tingkat rendah dan membuatnya lebih mudah untuk dipahami ( uint64_tbukan long longtipe, yaitu 8 byte).

Namun, ada uint_fast32_tyang memiliki kesamaan typedefdengan uint32_t. Akankah menggunakan versi "cepat" membuat program lebih cepat?

Amumu
sumber
panjang mungkin bukan 8 byte, mungkin panjang dengan 1 byte (dalam kasus CHAR_BIT setidaknya 64) atau dengan 3738383 byte. juga uint64_t bisa 1,2,4 atau 8 byte, CHAR_BIT harus 64, 3, 16 atau 8 untuk itu.
12431234123412341234123

Jawaban:

135
  • intmungkin sekecil 16 bit pada beberapa platform. Ini mungkin tidak cukup untuk aplikasi Anda.
  • uint32_ttidak dijamin ada. Merupakan opsional typedefbahwa implementasi harus menyediakan iff yang memiliki tipe integer yang tidak bertanda tangan persis 32-bit. Beberapa memiliki byte 9-bit misalnya, jadi mereka tidak memiliki fileuint32_t .
  • uint_fast32_tmenyatakan maksud Anda dengan jelas: ini adalah jenis setidaknya 32 bit yang terbaik dari sudut pandang kinerja. uint_fast32_tsebenarnya mungkin 64 bit. Terserah implementasinya.

... ada uint_fast32_tyang memiliki typedef yang sama seperti uint32_t...

Apa yang Anda lihat bukanlah standar. Ini adalah implementasi tertentu (BlackBerry). Jadi Anda tidak bisa menyimpulkan dari sana bahwa uint_fast32_tselalu sama dengan uint32_t.

Lihat juga:

Yakov Galka
sumber
36
Jawaban yang bagus. Untuk kelengkapan, seseorang mungkin bisa menunjukkan perbedaannya uint_least32_tjuga, yang sama uint_fast32_tkecuali itu lebih menyukai penyimpanan yang lebih kecil daripada kecepatan.
Damon
2
Mengapa bilangan bulat tercepat yang memiliki lebar setidaknya 32-bit menjadi lebih besar dari 32-bit? Saya selalu berpikir jika ada lebih sedikit bit, akan ada lebih sedikit bit yang harus dikerjakan CPU, jadi lebih cepat. Apa yang kulewatkan di sini?
Shane Hsu
12
@ShaneHsu: katakanlah cpu 64-bit akan memiliki musim panas 64-bit, yang menjumlahkan angka 64-bit dalam satu siklus. Tidak masalah jika yang ingin Anda lakukan hanyalah mengerjakan nomor 32-bit, itu tidak akan lebih cepat dari satu siklus. Sekarang, meskipun tidak demikian pada x86 / amd64, integer 32-bit bahkan mungkin tidak dapat dialamatkan. Dalam kasus seperti itu, mengerjakannya membutuhkan operasi tambahan untuk mengekstrak 32-bit dari, katakanlah, unit selaras 64-bit. Lihat juga pertanyaan terkait. Standar C ++ ditulis agar dapat bekerja pada mesin yang memiliki kata 37-bit ... jadi tidak ada tipe 32-bit sama sekali.
Yakov Galka
42

Perbedaannya terletak pada ketepatan dan ketersediaannya.

The doc sini mengatakan:

tipe integer unsigned dengan lebar persis 8, 16, 32 dan 64 bit masing-masing ( disediakan hanya jika implementasi mendukung tipe secara langsung ):

uint8_t
uint16_t
uint32_t
uint64_t

Dan

tipe integer unsigned unsigned tercepat dengan lebar minimal 8, 16, 32 dan 64 bit masing-masing

uint_fast8_t
uint_fast16_t
uint_fast32_t
uint_fast64_t    

Jadi perbedaannya cukup jelas yaitu uint32_tjenis yang memiliki bit persis 32 , dan implementasi harus menyediakannya hanya jika ia memiliki jenis dengan persis 32 bit, dan kemudian dapat mengetikkan jenis itu sebagai uint32_t. Artinya, uint32_tmungkin atau mungkin tidak tersedia .

Di sisi lain, uint_fast32_tadalah tipe yang memiliki setidaknya 32 bit, yang juga berarti, jika sebuah implementasi dapat mengetikef uint32_tseolah- uint_fast32_t olah menyediakan uint32_t. Jika tidak tersedia uint32_t, maka uint_fast32_tbisa menjadi typedef jenis apa pun yang memiliki setidaknya 32bit.

Nawaz
sumber
3
Tetapi apa alasan yang membuat misalnya uint_fast32_t lebih cepat dari uint32_t? Mengapa lebih cepat?
Destructor
2
@PravasiMeet: Tidak semua integer diakses dengan cara yang sama. Beberapa lebih mudah diakses daripada yang lain. Lebih mudah berarti lebih sedikit komputasi, lebih langsung, yang menghasilkan akses lebih cepat. Sekarang uint32_ttepat 32-bit di semua sistem (jika ada), yang mungkin tidak lebih cepat dibandingkan dengan yang memiliki, katakanlah, 64-bit. uint_fast32_tdi sisi lain setidaknya 32 bit, bahkan bisa 64-bit.
Nawaz
10
@Destructor: Pada beberapa prosesor, jika sebuah variabel disimpan dalam register yang lebih panjang, kompilator mungkin harus menambahkan kode tambahan untuk memotong bit ekstra. Misalnya, jika uint16_t x;disimpan dalam register 32-bit di ARM7-TDMI, kode x++;mungkin perlu dievaluasi sebagai x=((x+1)<<16)>>16);. Pada kompiler untuk platform itu, uint_fast16_tkemungkinan besar akan didefinisikan sebagai sinonim uint32_tuntuk menghindari itu.
supercat
kenapa [u]int_(fast|least)N_ttidak juga opsional? Tentunya tidak semua arsitektur dibutuhkan oleh Standard untuk mendukung tipe primitif setidaknya 64 bit? Namun kata-kata untuk stdint.hmenyiratkan bahwa mereka harus. Tampaknya aneh bagi saya bahwa kami telah menegakkannya sejak 1999, beberapa tahun sebelum komputasi 64-bit menjadi arus utama - untuk tidak mengatakan apa-apa tentang kelambatan di belakang (dalam banyak kasus masih saat ini) dari arsitektur yang disematkan. Ini tampak seperti pengawasan besar bagi saya.
underscore_d
1
@underscore_d: Tidak ada alasan khusus, misalnya, bahwa Standar tidak dapat diterapkan pada implementasi PIC12 dengan 16 byte RAM data dan ruang untuk 256 instruksi. Implementasi seperti itu perlu menolak banyak program, tetapi itu tidak boleh mencegahnya berperilaku dalam mode yang ditentukan untuk program yang kebutuhannya dapat dipenuhi.
supercat
4

Saat kamu #include inttypes.h dalam program Anda, Anda mendapatkan akses ke banyak cara berbeda untuk mewakili bilangan bulat.

Tipe uint_fast * _t mendefinisikan tipe tercepat untuk mewakili sejumlah bit.

Pikirkan seperti ini: Anda mendefinisikan variabel tipe shortdan menggunakannya beberapa kali dalam program, yang benar-benar valid. Namun, sistem yang sedang Anda kerjakan mungkin bekerja lebih cepat dengan nilai tipe int. Dengan mendefinisikan variabel sebagai tipeuint_fast*t , komputer hanya memilih representasi paling efisien yang dapat dikerjakannya.

Jika tidak ada perbedaan antara representasi ini, maka sistem akan memilih salah satu yang diinginkannya, dan menggunakannya secara konsisten.

Harley Sugarman
sumber
9
Mengapa inttypes.h dan bukan stdint.h? Tampaknya inttypes.h hanya berisi berbagai fluff yang sedikit berguna, ditambah dengan stdint.h?
Lundin
@underscored Saya tahu perbedaannya. Tetapi siapa yang menggunakan stdio.h dalam program profesional, apa pun bidang aplikasinya?
Lundin
@Lundin Saya tidak tahu siapa mereka, atau apakah mereka ada! Saya hanya berpikir mungkin berguna untuk memberikan tautan yang menjelaskan tentang apa itu "bulu yang sedikit berguna" ;-) Mungkin ini akan membantu orang menyadari bahwa Anda benar dan mereka tidak membutuhkannya.
underscore_d
-1

Perhatikan bahwa versi cepat bisa lebih besar dari 32 bit. Sementara int cepat akan cocok dengan baik di register dan disejajarkan dan sejenisnya: tetapi, itu akan menggunakan lebih banyak memori. Jika Anda memiliki array yang besar, program Anda akan lebih lambat karena lebih banyak hits cache memori dan bandwidth.

Saya tidak berpikir CPUS modern akan mendapatkan keuntungan dari fast_int32, karena umumnya tanda perluasan 32 hingga 64 bit dapat terjadi selama instruksi pemuatan dan gagasan bahwa ada format bilangan bulat 'asli' yang lebih cepat adalah kuno.

Gil Colgate
sumber