Mengapa tipe integer cepat lebih cepat daripada tipe integer lainnya?

107

Dalam ISO / IEC 9899: 2018 (C18), dinyatakan di bawah 7.20.1.3:

7.20.1.3 Jenis integer lebar minimum minimum

1 Masing-masing tipe berikut menunjuk tipe integer yang biasanya tercepat 268) untuk beroperasi dengan semua tipe integer yang setidaknya memiliki lebar yang ditentukan.

2 Nama typedef int_fastN_tmenunjuk tipe integer tercepat yang ditandatangani dengan lebar setidaknya N. Nama typedef uint_fastN_tmenunjuk tipe integer tercepat yang tidak ditandatangani dengan lebar setidaknya N.

3 Jenis-jenis berikut ini diperlukan:

int_fast8_t, int_fast16_t, int_fast32_t, int_fast64_t, uint_fast8_t, uint_fast16_t, uint_fast32_t,uint_fast64_t

Semua tipe lain dari formulir ini adalah opsional.


268) Jenis yang ditunjuk tidak dijamin tercepat untuk semua keperluan; jika implementasi tidak memiliki alasan yang jelas untuk memilih satu jenis di atas yang lain, itu hanya akan memilih beberapa jenis bilangan bulat memenuhi persyaratan ketelitian dan lebar.


Tetapi tidak disebutkan mengapa tipe integer "cepat" ini lebih cepat.

  • Mengapa tipe integer cepat ini lebih cepat daripada tipe integer lainnya?

Saya menandai pertanyaan dengan C ++, karena tipe integer cepat juga tersedia di C ++ 17 di file header cstdint. Sayangnya, dalam ISO / IEC 14882: 2017 (C ++ 17) tidak ada bagian seperti itu tentang penjelasan mereka; Saya telah menerapkan bagian itu di badan pertanyaan.


Informasi: Di ​​C, mereka dideklarasikan di file header stdint.h.

RobertS mendukung Monica Cellio
sumber
24
Poin kunci di sini adalah bahwa tipe integer ini tidak terpisah, tipe ajaib lebih cepat. Mereka hanyalah alias untuk tipe normal apa pun yang tercepat di mesin itu untuk operasi itu.
mtraceur
3
Kompiler memancarkan opcode operasi CPU untuk memuat, menyimpan, menutupi dan memodifikasi lokasi memori dan register ukuran tertentu; hanya itu yang dilihat CPU. Sistem operasi tidak ada hubungannya sama sekali. Ini semua pekerjaan kompiler, persis seperti jika Anda telah menentukan typedef yang diberikan sendiri. (Saya kira seorang kompiler diperbolehkan untuk memprosesnya secara internal secara berbeda - mungkin lebih efisien, jika itu mungkin - dibandingkan dengan yang diketik pengguna, selama tidak ada perbedaan perilaku yang terlihat.)
Peter - Reinstate Monica
1
@ RobertS-ReinstateMonica Lebih tepatnya, "alias" ini hanyalah typedefpernyataan. Jadi biasanya , ini dilakukan di tingkat perpustakaan standar. Tentu saja, C menempatkan standar tidak nyata pembatasan apa yang mereka typedefke - jadi misalnya implementasi khas adalah untuk membuat int_fast32_tsuatu typedefdari intpada sistem 32-bit, tapi compiler hipotetis bisa misalnya menerapkan __int_fastjenis intrinsik dan berjanji untuk melakukan beberapa mewah optimisasi untuk memilih jenis mesin tercepat berdasarkan kasus per kasus untuk variabel dari jenis itu, dan kemudian perpustakaan bisa typedefmelakukannya.
mtraceur
1
@ RobertS-ReinstateMonica Ya, benar. Anda mendapatkan program kinerja maksimum dengan flag kompilasi spesifik arsitektur yang membuat biner lebih mudah dibawa-bawa.
Peter - Pasang kembali Monica
1
@ Roberts-ReinstateMonica Ini akan menjadi yang paling efisien pada platform itu disusun untuk , belum tentu pada .
HABO

Jawaban:

152

Bayangkan sebuah CPU yang hanya melakukan operasi aritmatika 64 bit. Sekarang bayangkan bagaimana Anda akan menerapkan penambahan 8 bit yang tidak ditandatangani pada CPU tersebut. Ini akan melibatkan lebih dari satu operasi untuk mendapatkan hasil yang tepat. Pada CPU seperti itu, operasi 64 bit lebih cepat daripada operasi pada lebar integer lainnya. Dalam situasi ini, semua Xint_fastY_tmungkin merupakan alias dari tipe 64 bit.

Jika CPU mendukung operasi cepat untuk tipe integer sempit dan karenanya tipe yang lebih luas tidak lebih cepat daripada tipe yang lebih sempit, maka Xint_fastY_ttidak akan menjadi alias dari tipe yang lebih luas daripada yang diperlukan untuk mewakili semua bit Y.

Karena penasaran, saya memeriksa ukuran implementasi tertentu (GNU, Linux) pada beberapa arsitektur. Ini tidak sama di semua implementasi pada arsitektur yang sama:

┌────╥───────────────────────────────────────────────────────────┐
 Y     sizeof(Xint_fastY_t) * CHAR_BIT                         
    ╟────────┬─────┬───────┬─────┬────────┬──────┬────────┬─────┤
     x86-64  x86  ARM64  ARM  MIPS64  MIPS  MSP430  AVR 
╞════╬════════╪═════╪═══════╪═════╪════════╪══════╪════════╪═════╡
 8   8       8    8      32   8       8     16      8   
 16  64      32   64     32   64      32    16      16  
 32  64      32   64     32   64      32    32      32  
 64  64      64   64     64   64      64    64      64  
└────╨────────┴─────┴───────┴─────┴────────┴──────┴────────┴─────┘

Perhatikan bahwa meskipun operasi pada tipe yang lebih besar mungkin lebih cepat, tipe seperti itu juga mengambil lebih banyak ruang dalam cache, dan dengan demikian menggunakannya tidak selalu menghasilkan kinerja yang lebih baik. Selain itu, orang tidak dapat selalu percaya bahwa implementasi telah membuat pilihan yang tepat sejak awal. Seperti biasa, pengukuran diperlukan untuk hasil yang optimal.


Tangkapan layar tabel, untuk pengguna Android:

Cuplikan layar dari tabel di atas

(Android tidak memiliki karakter menggambar kotak di mono font - ref )

eerorika
sumber
Komentar bukan untuk diskusi panjang; percakapan ini telah dipindahkan ke obrolan .
Samuel Liew
@RobertSsupportsMonicaCellio No. "tidak sama di semua arsitektur" juga benar, tetapi langsung terbukti dari data yang ditampilkan, jadi saya tidak akan menganggap perlu untuk menyatakan yang jelas. Saya hanya menunjukkan nilai dari satu implementasi, dan memang yang lain akan memiliki pilihan yang berbeda. Periksa misalnya x86-64 di windows. Anda akan menemukan ukuran yang berbeda dibandingkan dengan yang ditunjukkan di sini.
eerorika
@RobertSsupportsMonicaCellio Menurut pendapat saya, komentar ini relevan dengan jawabannya, dan sesuai di sini. Saya akan membiarkan moderator memindahkan mereka, jika mereka merasa perlu melakukannya.
eerorika
11

Mereka tidak, setidaknya tidak andal.

Tipe cepat hanyalah typedef untuk tipe biasa, namun terserah implementasi bagaimana mendefinisikannya. Mereka harus setidaknya ukuran yang diminta, tetapi mereka bisa lebih besar.

Memang benar bahwa pada beberapa arsitektur beberapa tipe integer memiliki kinerja yang lebih baik daripada yang lain. Sebagai contoh, implementasi ARM awal memiliki instruksi akses memori untuk kata-kata 32-bit dan untuk byte yang tidak ditandatangani, tetapi mereka tidak memiliki instruksi untuk setengah kata atau byte yang ditandatangani. Petunjuk setengah kata dan ditandatangani byte ditambahkan kemudian, tetapi mereka masih memiliki opsi pengalamatan kurang fleksibel, karena mereka harus disemir ke ruang penyandian cadangan. Selain itu semua instruksi pemrosesan data aktual pada ARM bekerja berdasarkan kata-kata, jadi dalam beberapa kasus mungkin perlu untuk menutup nilai yang lebih kecil setelah perhitungan untuk memberikan hasil yang benar.

Namun, ada juga kekhawatiran akan tekanan cache, bahkan jika dibutuhkan lebih banyak instruksi untuk memuat / menyimpan / memproses nilai yang lebih kecil. Nilai yang lebih kecil mungkin masih berkinerja lebih baik jika mengurangi jumlah kesalahan cache.

Definisi tipe pada banyak platform umum tampaknya tidak dipikirkan. Secara khusus, platform 64-bit modern cenderung memiliki dukungan yang baik untuk integer 32-bit, namun tipe "cepat" seringkali tidak perlu 64-bit pada platform ini.

Selanjutnya, ketik C menjadi bagian dari ABI platform. Jadi, bahkan jika vendor platform menemukan mereka membuat pilihan bodoh, sulit untuk mengubah pilihan bodoh itu nanti.

Abaikan jenis "cepat". Jika Anda benar-benar peduli dengan kinerja integer, patok kode Anda dengan semua ukuran yang tersedia.

plugwash
sumber
7

Tipe cepat tidak lebih cepat dari semua tipe integer lainnya - mereka sebenarnya identik dengan beberapa tipe integer "normal" (mereka hanya alias untuk tipe itu) - tipe mana pun yang paling cepat memegang nilai setidaknya banyak bit.

Itu hanya tergantung platform mana tipe integer setiap jenis cepat adalah alias untuk.

Chris Dodd
sumber