Standart komitelerin önem verdiği egzotik mimariler


154

C ve C ++ standartlarının dil uygulamasının tanımlı birçok yönünü bıraktığını biliyorum, çünkü diğer özelliklere sahip bir mimari varsa, bunun için standart uygun bir derleyici yazmak çok zor veya imkansız olurdu.

40 yıl önce herhangi bir bilgisayarın kendine özgü özellikleri olduğunu biliyorum. Ancak, bugün kullanılan herhangi bir mimariyi bilmiyorum:

  • CHAR_BIT != 8
  • signed ikisinin tamamlayıcısı değil (Java'nın bu sorunla karşılaştığını duydum).
  • Kayan nokta IEEE 754 uyumlu değil (Düzenleme: "IEEE 754 ikili kodlamasında değil" demek istedim).

Soruyorum neden sık sık 's iyi C ++ sabit büyüklükte türleri gibi başka düşük seviyeli yönlerini zorunlu kılmaz o insanlara açıklamak olmasıdır . İyi çünkü diğer dillerden farklı olarak kodunuzu doğru kullanıldığında taşınabilir hale getirir (Düzenle: makinenin düşük seviyeli yönlerinin emülasyonu gerektirmeden daha fazla mimariye taşınabilir, çünkü örneğin ikisinin işaret + büyüklük mimarisinde tamamlayıcı aritmetiği gibi) . Ama kendimi belirli bir mimariye işaret edemediğim için üzülüyorum.

Yani soru şu: yukarıdaki mimarileri hangi mimariler sergiliyor?

uint*_ts isteğe bağlıdır.


9
Bence geriye doğru sahipsin. C ++ imzalı tamsayılar için iki tamamlayıcıyı zorunlu kılsaydı, C ++ kodunu daha az değil daha taşınabilir hale getirirdi. C ++ standartlar komitesinin neden bunu zorunlu kılmadığı sorusu başka bir konudur. Özellikle, söylediklerinize rağmen, standart olmayan bir mimari için bir derleyici yazmak imkansız olmayacağından, platformunuz doğrudan desteklemese bile her zaman 8 bit karakter veya iki tamamlayıcı aritmetik simüle edebilirsiniz.
john

8
@john: o zaman pratik değildir, bu yüzden standart olmayan uygun derleyici uygun olandan daha hızlı kod üretir. Ve hala kodunuzu nasıl daha taşınabilir hale getirdiğini göremiyorum.
Yakov Galka

4
Eminim standart olmanın asıl nedeni, bunun ideal bir çözüm olması değil. Ancak bunun yerine, standart yazıldığı zaman birçok C ve C ++ derleyicisi zaten mevcuttu ve standartlar komitesi mevcut derleyicileri reddetmek istemedi.
john

4
@john: C ++ standardını oluştururken "derleyici yazarları kolaylaştırmak" ın bir öncelik olduğundan şüphe duyuyorum (eğer C ++ ayrıştırılması en zor dillerden biri ve diğer yönleri dil derleyici yazarları için de tam olarak kolay değildir). Performans, geniş platform desteği ve geriye dönük uyumluluk oldukça önemlidir. Ve bahsettiğiniz kısıtlamaların standarda eklenmesi durumunda bu üçü de zarar görecektir.
Sander De Dycker

5
Derleyici değil donanım ile ilgili. C ++, donanım özelliklerinin doğrudan kullanımına izin vermek için bazı şeyleri belirtilmemiş bırakır. Telefon uygulamalarınız yine de bir ana bilgisayarda çalışmaz, bu nedenle kodla uyumlu bir taşınabilirlik yoktur.
Bo Persson

Yanıtlar:


114

Buna bir göz at

Unisys ClearPath Dorado Sunucuları

henüz tüm Univac yazılımlarını taşımayan kişiler için geriye dönük uyumluluk sunar.

Anahtar noktaları:

  • 36 bit kelimeler
  • CHAR_BIT == 9
  • tamamlayıcı
  • 72 bit IEEE olmayan kayar nokta
  • kod ve veriler için ayrı adres alanı
  • Kelime-ele
  • özel yığın işaretçisi yok

Onlar olsa C ++ derleyicisi teklif olmadığını bilmek, ama onlar etmeyin olabilir .


Ve şimdi C kılavuzlarının son sürümlerine bir bağlantı ortaya çıktı:

Unisys C Derleyici Programlama Referans Kılavuzu

Bölüm 4.5, 9, 18, 36 ve 72 bitlik bir veri türü tablosuna sahiptir.

C derleyicisindeki veri türü boyutu ve aralığı


13
Bu mimaride void * kullanmak cehennem olmalı sanırım.
luiscubal

13
@ybungalobill - İnanıyorum char*ve void*aynı boyutta olmalı ve başka bir işaretçiyi tutacak kadar büyük olmalıdır. Gerisi uygulamaya bağlı.
Bo Persson

22
@ybungalobill: Eski Win16 derleyicilerinde, normal işaretçiler işaretçilerin yakınındaydı ve sadece 16 bitlik bir sapma içeriyordu, bu yüzden sizeof(int*) == 2uzak işaretçilerin de 16 bitlik bir seçici vardı sizeof(void*) == 4.
Adam Rosenfield

10
C ++ derleyicileri için çevrimiçi bir kılavuz vardır veya eskidir. Bunun Unisys anabilgisayar mimarilerinden sadece biri olduğunu belirtmek gerekir: diğeri 48 bit imzalı büyüklük etiketli bir mimaridir (bunun için sadece bir C el kitabı buldum, C ++ bir değil). Gerisi ile ilgili: Bence sizeof(int*) != sizeof(char*)burada: her ikisi de 36 bit. Ancak içindeki bayt seçici char*yüksek dereceli bitlerde ve yok sayılır int*. (Ancak, `` sizeof (char *)> sizeof (int *) 'de başka makineler kullandım.)
James Kanze

16
@Adam Rosenfield MS / DOS 16 bit derleyicilerinde farklı "modlar" vardı ve veri işaretçileri mutlaka işlev işaretçileriyle aynı boyutta değildi. Ama en azından kullandıklarımda, tüm veri işaretçileri (dahil void*) her zaman aynı boyuta sahipti. (Tabii ki, bir işlev işaretçisi dönüştürmek olamazdı void*çünkü void*. Ya, daha küçük olabilir Ama standardına göre, bu bugün yapamaz.)
James Kanze

51

Varsayımlarınızın hiçbiri ana kareler için geçerli değildir. Yeni başlayanlar için, IEEE 754 kullanan bir ana bilgisayar bilmiyorum: IBM, taban 16 kayan noktasını kullanıyor ve Unisys ana bilgisayarlarının her ikisi de taban 8 kullanıyor. Unisys makineleri, diğer birçok açıdan biraz özel: Bo, 2200'den bahsetti MPS mimarisi daha da garip: 48 bit etiketli kelimeler. (Kelimenin bir işaretçi olup olmadığı, kelimedeki bir bite bağlıdır.) Sayısal gösterimler, kayan nokta ile integral aritmetik arasında gerçek bir ayrım olmayacak şekilde tasarlanmıştır: kayan nokta taban 8'dir; normalleştirme gerektirmez ve gördüğüm diğer kayan noktalardan farklı olarak, ondalık sayıyı soldan ziyade mantisin sağına koyar ve üs için işaretli büyüklük kullanır (mantisin yanı sıra). Bir integral kayan nokta değerinin işaretli bir büyüklük tamsayısı ile aynı bit gösterimine sahip olduğu (veya sahip olabileceği) sonuçlarla Ve kayan nokta aritmetik komutları yoktur: iki değerin üslerinin her ikisi de 0 ise, komut integral aritmetiği yapar, aksi takdirde kayan nokta aritmetiği yapar. (Mimaride etiketleme felsefesinin devamı.)int 48 bit içerebilir, 8 tanesi 0 olmalıdır veya değer bir tamsayı olarak değerlendirilmez.


4
IBM ana çerçeveleri (z / Mimari) IEE754 kayan noktayı destekler.
Nikita Nemkin

1
fyi

6
@Nikita - Şimdi yapıyorlar . Başlangıçta Java'yı desteklemek için (pahalı) bir eklentiydi.
Bo Persson


42

Kayan noktalı uygulamalarda tam IEEE 754 uyumluluğu nadirdir. Ve bu konuda spesifikasyonu zayıflatmak birçok optimizasyona izin verir.

Örneğin alt norm desteği x87 ve SSE arasında farklılık gösterir.

Kaynak kodunda ayrı olan bir çarpma ve ekleme gibi optimizasyonlar da sonuçları biraz değiştirir, ancak bazı mimarilerde hoş bir optimizasyon olur.

Ya da x86'da katı IEEE uyumluluğu, 80bit dahili kayan yerine belirtilen kayan nokta türünü kullanmaya zorlamak için kayan nokta kayıtları ve normal bellek arasında belirli bayrakların ayarlanmasını veya ek transferler gerektirebilir.

Ve bazı platformların hiçbir donanım şamandırası yoktur ve bu nedenle bunları yazılımda taklit etmeleri gerekir. Ve IEEE 754'ün bazı gereksinimlerinin yazılımda uygulanması pahalı olabilir. Özellikle yuvarlama kuralları bir sorun olabilir.

Sonuç olarak, her zaman katı IEEE uyumluluğunu garanti etmek istemediğiniz durumlarda, durumlara girmek için egzotik mimarilere ihtiyacınız olmadığıdır. Bu nedenle, birkaç programlama dili katı IEEE uyumluluğunu garanti ediyordu.


7
Başka bir "egzotik" donanım seti, kayan nokta biçiminin IEEE standardından önce geldiği IBM ana çerçeveleri. Java'nın aksine, C ++ mevcut donanımı kullanabilir.
Bo Persson

5
IEEE 754, GPU'lar tarafından tam olarak desteklenmez.
kerem

3
IEEE 754'e sıkı sıkıya uyulmaması, bazılarını rahatsız ediyor, ancak OP'nin gerçekten önem verdiği konular kapsamında olduğunu sanmıyorum.
şeye kadir

3
@Matthieu Bu da "C" olarak etiketlendiğinden, kayan noktalı programınızın C derleyicisinin kaprisinde belleğe dökülen 80 bit kayan noktalı kayıt ile alabileceği tüm değerleri söyleyebilen bir C analizcisinden bahsetmeliyim. blog.frama-c.com/index.php?post/2011/03/03/cosine-for-real
Pascal Cuoq

2
@MatthieuM .: Çok kötü ISO / ANSI değişken değişken parametrelerin kayan nokta ve tamsayı bağımsız değişkenleri için minimum / maksimum boyutlarını belirtmesine izin vermedi; eğer olsaydı, 80-bit long doubleyararlı ve uzun ömürlü bir tip olabilirdi, çünkü onunla ilgili tek sorun kötü çalıştığıydı printf. Genişletilmiş çiftin önde gelen 1'i depolaması, FPU dışı sistemlerde hesaplamaları açıkça hızlandırır ve aynı zamanda diğer türlere dönüştürmelerden / başka türlerden dönüşümler dışında herhangi bir bağlamda denormallerin özel olarak ele alınması ihtiyacını ortadan kaldıracaktır. Çok kötü C printfher şeyi mahvetti.
supercat

40

Bulduğum bazı sistemlerin listeleyen bu bağlantıyı nerede CHAR_BIT != 8. İçerirler

bazı TI DSP'leri CHAR_BIT == 16

BlueCore-5 yongası (Cambridge Silicon Radio'dan bir Bluetooth yongası) CHAR_BIT == 16.

Ve elbette Stack Overflow ile ilgili bir soru var: Hangi platformlarda 8 bit karakterden başka bir şey var?

İkisinin tamamlayıcı olmayan sistemlerine gelince, comp.lang.c ++ 'da ılımlı bir okuma var . Özetle: tamamlayıcı veya işaret ve büyüklük temsili olan platformlar vardır.


5
Analog Devices 32-bit SHARC DSP CHAR_BIT=32ve TMS32F28xx Texas Instruments DSP'ye sahiptir CHAR_BIT=16. PDP-10 için GCC 3.2 vardır CHAR_BIT=9. Bence, S / 360 da 8bit olmayan bir karaktere sahip olabilir.
osgx

1
Hala 'ikisinin tamamlayıcısı olmayan' mimarilere bir örnek istiyorum. Özellikle de CHAR_BITSkısmen olduğu için.
Yakov Galka

TI DSP'lerin yalnızca uygulayıcıların seçtiği için 16 bit karakterleri var (doğru çalışması için biraz daha fazla iş olurdu, ama saçma zor IIRC değil - muhtemelen temel derleyicideki kodgen iskelesinde sadece bazı “delikler”) . Bu yüzden derin bir mimari neden değil. C kodu soyut bir makinede çalışır. Sahip olduğunuz tek şey 16-bit INT ise, her birinde iki karakter saklayın ve gözetleme deliği optimize edicisine okuma-değiştirme-yazma birleştirme ekleyin (en azından). Tabii, bu daha fazla iş, ama sadece herkesin bu kadar tuhaf tiplerle başa çıkmayacakları yerlerde ne kadar fazla iş yapması gerektiğine bakın. Yuck.
Monica'yı

24

VAX sistemlerinin hala kullanımda olduğundan eminim. IEEE kayan noktasını desteklemezler; kendi biçimlerini kullanırlar. Alpha hem VAX hem de IEEE kayan nokta biçimlerini destekler.

T90 gibi cray vektör makineleri de kendi kayan nokta formatına sahiptir, ancak daha yeni Cray sistemleri IEEE kullanır. (Kullandığım T90 birkaç yıl önce hizmet dışı bırakıldı; hala aktif kullanımda olup olmadığını bilmiyorum.)

T90'ın ayrıca işaretçiler ve tamsayılar için bazı ilginç sunumları vardı / var. Yerel bir adres yalnızca 64 bitlik bir kelimeyi gösterebilir. C ve C ++ derleyicilerinde CHAR_BIT == 8 (Unix'in bir çeşidi olan Unicos'u çalıştırdığı ve diğer sistemlerle birlikte çalışması gerektiğinden gerekliydi) vardı, ancak yerel bir adres yalnızca 64 bitlik bir kelimeyi gösterebilirdi. Tüm bayt seviyesi işlemleri derleyici tarafından sentezlendi ve bir void*veya char*bayt uzaklığı kelimenin yüksek dereceli 3 bitinde saklandı. Bence bazı tamsayı tiplerinde dolgu bitleri vardı.

IBM ana çerçeveleri başka bir örnektir.

Öte yandan, bu özel sistemlerin dil standardındaki değişiklikleri mutlaka engellemesi gerekmez . Cray, C derleyicisini C99'a yükseltmeye özel bir ilgi göstermedi; muhtemelen aynı şey C ++ derleyicisine uygulanır. Olabilir imzalı tamsayı için dolgu bitleri olmadan böyle CHAR_BIT == 8 gerektiren IEEE biçimi kayan nokta olmasa tam semantik ve 2's-tamamlayıcısı olarak barındırılan uygulamalar için gereksinimleri, sıkılaştırmak için makul ol. Eski sistemler daha önceki dil standartlarını desteklemeye devam edebilir (C99 çıktığında C90 ölmedi) ve DSP'ler gibi bağımsız uygulamalar (gömülü sistemler) için gereksinimler daha gevşek olabilir.

Öte yandan, gelecekteki sistemlerin bugün egzotik kabul edilecek şeyleri yapmaları için iyi nedenler olabilir .


6
Son derece katı standartların yeniliği nasıl önlediği konusunda iyi bir nokta. Üçlü durumlara sahip kuantum (veya organik) bilgisayarlar elde ettiğimizde, unsignedintegral tipler için modulo aritmetik gereksinimleri büyük bir acı olurken, imzalı aritmetik iyi olacaktır.
Ben Voigt

@BenVoigt Bu imzasız aritmetik neden bir acıdır? Bu bilgisayarlarda modulo 3 ^ n toplayıcı mümkün değil mi?
phuclv

2
@ LưuVĩnhPhúc: Modulo 3 ** n yapılan donanım işlemleri ile, işlemleri modulo 2 ** n olarak tanımlanan C ++ imzasız türleri sağlamak tam da bu noktada zor olacaktır.
Ben Voigt

2
Özel bir mimariye sahip özel bir gömülü sistemi hedefleyen bir çapraz derleyici için ana bilgisayar olarak kullanılmakta olan bir VAX 11/780'i biliyorum. Özel VAX'ı sürdürmek için, saklama görevlileri yedek parça müzelerine yaklaşıyor.
Peter

2
@ Keith - teknik olarak, tek engel, hedef gömülü sistem yüksek kritiklik olduğundan, düzenleyici gereksinimleri karşılayacak kanıt sağlama sürecinden geçmektedir. Bununla birlikte, bugüne kadar aşılamayan bir takım teknik olmayan engeller (örgütsel politikalar, vb.) Vardır. Şu anda müzeleri basmak için bir davayı monte etmek ev sahibini güncellemekten daha kolaydır.
Peter

16

CHAR_BITS

Göre gcc kaynak kodu:

CHAR_BITolduğu 16için bit 1750a , dsp16xx mimarileri.
CHAR_BITolduğu 24için bit dsp56k mimari.
CHAR_BITolduğu 32için bit c4x mimari.

Aşağıdakileri yaparak daha fazlasını kolayca bulabilirsiniz:

find $GCC_SOURCE_TREE -type f | xargs grep "#define CHAR_TYPE_SIZE"

veya

find $GCC_SOURCE_TREE -type f | xargs grep "#define BITS_PER_UNIT"

Eğer CHAR_TYPE_SIZEuygun şekilde tanımlanır.

IEEE 754 uyumluluğu

Hedef mimari kayan nokta yönergelerini desteklemiyorsa, gcc varsayılan olarak standart uyumlu olmayan yazılım yedek cadı oluşturabilir. Dahası, özel seçenekler ( -funsafe-math-optimizationscadı gibi sıfırlar için işaret korumayı devre dışı bırakır) kullanılabilir.


3
OP'yi popüler bir derleyicinin kaynağına bakması için yönlendirmek için oy verildi; bu, bu durumda RFTM'nin tanımıdır, bu yüzden insanların ilk baktığı yer olmalıdır.
underscore_d

9

IEEE 754 ikili temsili GPU'larda yakın zamana kadar yaygın değildi, bkz. GPU Kayan Nokta Paranoyası .

EDIT: yorumlarda GPU kayan noktasının grafiklerle ilgisi olmayan olağan bilgisayar programlaması ile ilgili olup olmadığı sorusu gündeme gelmiştir. Tabi lan! Bugün endüstriyel olarak hesaplanan en yüksek performanslı şey GPU'larda yapılır; liste yapay zekayı, veri madenciliğini, sinir ağlarını, fiziksel simülasyonları, hava tahminini ve çok daha fazlasını içerir. Yorumlardaki bağlantılardan biri nedenini gösterir: GPU'ların büyüklük kayan nokta avantajı sırası .

Eklemek istediğim başka bir şey, OP sorusuyla daha ilgili: insanlar 10-15 yıl önce GPU kayan noktası IEEE olmadığında ve GPU'ları programlamak için bugünün OpenCL veya CUDA gibi bir API olmadığında ne yaptılar? İster inanın ister inanmayın, erken GPU hesaplama öncüleri bunu yapmak için bir API olmadan GPU'ları programlamayı başardılar ! Bunlardan biriyle şirketimde tanıştım. Yaptığı şudur: hesaplamak için ihtiyaç duyduğu verileri, üzerinde çalıştığı değerleri temsil eden piksellerle bir görüntü olarak kodladı, daha sonra ihtiyaç duyduğu işlemleri yapmak için OpenGL'yi kullandı (örneğin, normal dağılımlı bir evrişimi temsil etmek için "gaussian blur") , vb.) ve sonuçta elde edilen görüntüyü bir sonuç dizisine geri çözdü. Ve bu hala CPU kullanmaktan daha hızlıydı!

NVidia'yı nihayet dahili veri ikili dosyalarını IEEE ile uyumlu hale getirmeye ve görüntü manipülasyonundan ziyade hesaplamaya yönelik bir API tanıtmaya iten şey budur.


GPU'lar nasıl alakalı? (a) Bu sayfa çok eski görünüyor . (b) Bu güne kadar, GPU'ları C'de programlayamazsınız: C, GPU'ların bildiklerime göre desteklemediği özyinelemeli işlevler gibi şeyleri destekliyor. Yani istersen derleyici bile yazamazsın.
Yakov Galka

1
@ybungalobill, tekrar eden çalışmaları GPU'ya boşaltma, şu anda büyük ölçekli hesaplamalar için tercih edilen yöntemdir . Aslında, şu anda C ++ 'da bir tane geliştiriyorum. Neyse ki, yalnızca IEEE 754 uyumlu ikili gösterimine sahip NVidia CUDA GPU'larla çalışıyoruz .
Michael

GPU'ların GP hesaplamaları için kullanılmadığını söylemiyorum. Sözdizimi benzerliğine rağmen, çekirdekleri gerçekten C dilinde programlamadığınızı söyledim. int f(int n) { return n <= 1 ? 1 : n * f(n-1); }CUDA'da icra edebilir misin ? Hayır ise, GPU'lar bu soru ile ilgili değildir (C ve C ++ komitelerini sorar).
Yakov Galka

6
@ybungalobill: buna birkaç cevap. İlk olarak, CUDA C, C ++ ve Fortran'ı destekliyor . 2048 iş parçacığı GPU'ların tipik 8 iş parçacıklı CPU'nuza göre olağanüstü performans avantajı için aynı bağlantıya bakın. İkincisi, doğru, CUDA 5.0'a kadar CUDA programlama modeli özyinelemesine ("dinamik paralellik" denir) uygun destek eksikliği de dahil olmak üzere, bu dillerin yalnızca alt kümeleri (büyük olanlar da dahil) desteklenir. Üçüncüsü, özyinelemelerin yerini, zaten çok iş parçacıklı performans için gerekli olan döngüler alabilir.
Michael
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.