Saya tahu bahwa standar C dan C ++ meninggalkan banyak aspek implementasi bahasa yang ditentukan hanya karena jika ada arsitektur dengan karakteristik lain, akan sangat sulit atau tidak mungkin untuk menulis kompiler yang sesuai standar untuk itu.
Saya tahu bahwa 40 tahun yang lalu komputer mana pun memiliki spesifikasi uniknya sendiri. Namun, saya tidak tahu ada arsitektur yang digunakan saat ini di mana:
CHAR_BIT != 8
signed
bukan pelengkap dua (saya mendengar Jawa punya masalah dengan yang satu ini).- Floating point tidak sesuai dengan IEEE 754 (Edit: Maksud saya "tidak dalam pengkodean biner IEEE 754").
Alasan saya bertanya adalah bahwa saya sering menjelaskan kepada orang-orang bahwa ada baiknya C ++ tidak mengamanatkan aspek tingkat rendah lainnya seperti tipe berukuran tetap † . Ini bagus karena tidak seperti 'bahasa lain' itu membuat kode Anda portabel ketika digunakan dengan benar (Edit: karena dapat porting ke lebih banyak arsitektur tanpa memerlukan emulasi aspek tingkat rendah dari mesin, seperti misalnya aritmatika komplemen dua pada arsitektur tanda + magnitude) . Tetapi saya merasa tidak enak karena saya sendiri tidak dapat menunjuk ke arsitektur tertentu.
Jadi pertanyaannya adalah: arsitektur apa yang memperlihatkan properti di atas?
Ini uint*_t
opsional.
sumber
Jawaban:
Lihatlah yang ini
Server Unisys ClearPath Dorado
menawarkan kompatibilitas ke belakang untuk orang-orang yang belum memigrasikan semua perangkat lunak Univac mereka.
Poin-poin penting:
CHAR_BIT == 9
Tidak tahu apakah mereka menawarkan kompiler C ++, tetapi mereka bisa .
Dan sekarang tautan ke edisi terbaru dari manual C mereka telah muncul:
Manual Referensi Pemrograman Unisys C Compiler
Bagian 4.5 memiliki tabel tipe data dengan 9, 18, 36, dan 72 bit.
sumber
char*
danvoid*
harus memiliki ukuran yang sama, dan cukup besar untuk menampung pointer lainnya. Sisanya terserah implementasi.sizeof(int*) == 2
, tetapi pointer jauh juga memiliki pemilih 16-bit, jadisizeof(void*) == 4
.sizeof(int*) != sizeof(char*)
sini: keduanya 36 bit. Tetapi pemilih byte dichar*
adalah pada bit urutan tinggi, dan diabaikan diint*
. (Saya telah menggunakan mesin lain, di mana `sizeof (char *)> sizeof (int *).)void*
) selalu memiliki ukuran yang sama. (Tentu saja, Anda tidak dapat mengonversi fungsi pointer kevoid*
, karenavoid*
mungkin lebih kecil. Tetapi menurut standar, Anda juga tidak dapat melakukannya hari ini.)Tidak ada asumsi Anda yang berlaku untuk mainframe. Sebagai permulaan, saya tidak tahu tentang mainframe yang menggunakan IEEE 754: IBM menggunakan basis 16 floating point, dan kedua mainframe Unisys menggunakan basis 8. Mesin Unisys sedikit istimewa dalam banyak hal lain: Bo telah menyebutkan 2200 arsitektur, tetapi arsitektur MPS bahkan lebih aneh: kata-kata dengan tag 48 bit. (Apakah kata itu penunjuk atau tidak tergantung pada sedikit kata tersebut.) Dan representasi numerik dirancang sedemikian rupa sehingga tidak ada perbedaan nyata antara titik mengambang dan aritmatika integral: titik mengambang adalah basis 8; itu tidak memerlukan normalisasi, dan tidak seperti setiap titik apung lain yang pernah saya lihat, itu menempatkan desimal di sebelah kanan mantissa, daripada ke kiri, dan menggunakan besaran yang ditandatangani untuk eksponen (di samping mantissa). Dengan hasil bahwa nilai floating point integral memiliki (atau dapat memiliki) representasi bit yang sama persis dengan integer magnitudo yang ditandatangani. Dan tidak ada instruksi aritmatika floating point: jika eksponen dari kedua nilai keduanya 0, instruksi melakukan aritmatika integral, jika tidak, itu aritmatika floating point. (Kelanjutan dari filosofi penandaan dalam arsitektur.) Yang berarti itu sementara
int
dapat menempati 48 bit, 8 di antaranya harus 0, atau nilainya tidak akan diperlakukan sebagai bilangan bulat.sumber
Kepatuhan penuh IEEE 754 jarang terjadi dalam implementasi floating-point. Dan melemahkan spesifikasi dalam hal itu memungkinkan banyak optimasi.
Misalnya dukungan subnorm berbeda antara x87 dan SSE.
Optimasi seperti menggabungkan penggandaan dan penambahan yang terpisah dalam kode sumber sedikit mengubah hasil juga, tetapi optimasi yang bagus pada beberapa arsitektur.
Atau pada x86 kepatuhan IEEE yang ketat mungkin memerlukan flag tertentu yang ditetapkan atau transfer tambahan antara register titik mengambang dan memori normal untuk memaksanya menggunakan jenis titik mengambang yang ditentukan alih-alih float 80bit internal.
Dan beberapa platform tidak memiliki perangkat keras mengapung sama sekali dan dengan demikian perlu meniru mereka dalam perangkat lunak. Dan beberapa persyaratan IEEE 754 mungkin mahal untuk diimplementasikan dalam perangkat lunak. Secara khusus aturan pembulatan mungkin menjadi masalah.
Kesimpulan saya adalah bahwa Anda tidak perlu arsitektur eksotis untuk masuk ke situasi yang Anda tidak selalu ingin menjamin kepatuhan IEEE yang ketat. Untuk alasan ini adalah beberapa bahasa pemrograman menjamin kepatuhan IEEE yang ketat.
sumber
long double
bisa menjadi tipe yang berguna dan berumur panjang, karena satu-satunya masalah dengan itu adalah bahwa ia bekerja dengan burukprintf
. Fakta bahwa perpanjangan ganda menyimpan angka 1 terdepan secara eksplisit mempercepat perhitungan pada sistem non-FPU dan juga akan menghilangkan perlunya penanganan khusus penolakan dalam konteks apa pun selain konversi ke / dari jenis lain. Sayang sekali Cprintf
mengacaukan semuanya.Saya menemukan tautan ini mendaftar beberapa sistem di mana
CHAR_BIT != 8
. Mereka termasukDan tentu saja ada pertanyaan tentang Stack Overflow: Platform apa yang memiliki sesuatu selain 8-bit char
Sedangkan untuk sistem non-komplemen ada bacaan menarik di comp.lang.c ++. Dimoderasi . Ringkasnya: ada platform yang memiliki pelengkap atau tanda dan representasi besarnya.
sumber
CHAR_BIT=32
, dan Texas Instruments DSP dari TMS32F28xx milikiCHAR_BIT=16
. GCC 3.2 untuk PDP-10 milikiCHAR_BIT=9
. Saya pikir, S / 360 mungkin memiliki char tidak-8bit juga.CHAR_BITS
adalah duplikat parsial.Saya cukup yakin bahwa sistem VAX masih digunakan. Mereka tidak mendukung IEEE floating-point; mereka menggunakan format mereka sendiri. Alpha mendukung format floating-point VAX dan IEEE.
Mesin vektor Cray, seperti T90, juga memiliki format floating-point sendiri, meskipun sistem Cray yang lebih baru menggunakan IEEE. (T90 yang saya gunakan dinonaktifkan beberapa tahun yang lalu; Saya tidak tahu apakah ada yang masih aktif digunakan.)
T90 juga memiliki / memiliki beberapa representasi menarik untuk pointer dan integer. Alamat asli hanya dapat menunjuk ke kata 64-bit. Kompiler C dan C ++ memiliki CHAR_BIT == 8 (diperlukan karena menjalankan Unicos, rasa Unix, dan harus beroperasi dengan sistem lain), tetapi alamat asli hanya dapat menunjuk pada kata 64-bit. Semua operasi tingkat byte disintesis oleh kompiler, dan a
void*
atauchar*
menyimpan byte offset dalam urutan tinggi 3 bit kata. Dan saya pikir beberapa tipe integer memiliki bit padding.Mainframe IBM adalah contoh lain.
Di sisi lain, sistem khusus ini tidak perlu menghalangi perubahan standar bahasa. Cray tidak menunjukkan minat khusus untuk meningkatkan kompiler C menjadi C99; agaknya hal yang sama diterapkan pada kompiler C ++. Ini mungkin masuk akal untuk memperketat persyaratan untuk implementasi host, seperti membutuhkan CHAR_BIT == 8, Format IEEE floating-point jika tidak semantik penuh, dan 2's-pelengkap tanpa bantalan bit untuk bilangan bulat ditandatangani. Sistem lama dapat terus mendukung standar bahasa sebelumnya (C90 tidak mati ketika C99 keluar), dan persyaratannya bisa lebih longgar untuk implementasi freestanding (embedded system) seperti DSP.
Di sisi lain, mungkin ada alasan bagus untuk sistem masa depan untuk melakukan hal-hal yang dianggap eksotis hari ini.
sumber
unsigned
tipe integral akan menjadi masalah besar, sementara aritmatika yang ditandatangani akan baik-baik saja.CHAR_BITS
Menurut kode sumber gcc :
CHAR_BIT
adalah16
bit untuk 1750a , dsp16xx arsitektur.CHAR_BIT
adalah24
bit untuk arsitektur dsp56k .CHAR_BIT
adalah32
bit untuk arsitektur c4x .Anda dapat dengan mudah menemukan lebih banyak dengan melakukan:
atau
jika
CHAR_TYPE_SIZE
didefinisikan dengan tepat.Kepatuhan IEEE 754
Jika arsitektur target tidak mendukung instruksi floating point, gcc dapat menghasilkan penyihir fallback perangkat lunak tidak sesuai standar secara default. Lebih dari itu, opsi khusus (seperti
-funsafe-math-optimizations
penyihir juga menonaktifkan tanda melestarikan untuk nol) dapat digunakan.sumber
Representasi biner IEEE 754 tidak umum pada GPU sampai saat ini, lihat GPU Floating-Point Paranoia .
EDIT: pertanyaan telah diajukan dalam komentar apakah GPU floating point relevan dengan pemrograman komputer biasa, tidak terkait dengan grafik. Yeah! Sebagian besar hal kinerja tinggi yang dihitung secara industri saat ini dilakukan pada GPU; daftar termasuk AI, penambangan data, jaringan saraf, simulasi fisik, ramalan cuaca, dan banyak lagi. Salah satu tautan dalam komentar menunjukkan alasannya: urutan keunggulan floating point GPU.
Hal lain yang ingin saya tambahkan, yang lebih relevan dengan pertanyaan OP: apa yang dilakukan orang 10-15 tahun lalu ketika GPU floating point bukan IEEE dan ketika tidak ada API seperti OpenCL atau CUDA hari ini untuk memprogram GPU? Percaya atau tidak, pelopor komputasi GPU awal berhasil memprogram GPU tanpa API untuk melakukannya ! Saya bertemu salah satu dari mereka di perusahaan saya. Inilah yang dia lakukan: dia menyandikan data yang dia perlukan untuk menghitung sebagai gambar dengan piksel yang mewakili nilai yang sedang dikerjakannya, kemudian menggunakan OpenGL untuk melakukan operasi yang diperlukannya (seperti "gaussian blur" untuk mewakili konvolusi dengan distribusi normal. , dll), dan mendekodekan gambar yang dihasilkan kembali ke dalam array hasil. Dan ini masih lebih cepat daripada menggunakan CPU!
Hal-hal seperti itulah yang mendorong NVidia untuk akhirnya membuat data biner internal mereka kompatibel dengan IEEE dan untuk memperkenalkan API yang berorientasi pada perhitungan daripada manipulasi gambar.
sumber
int f(int n) { return n <= 1 ? 1 : n * f(n-1); }
di CUDA? Jika tidak, maka GPU tidak relevan untuk pertanyaan ini (yang menanyakan tentang komite C dan C ++).