2 puan yazan GN⁺ 2024-10-07 | 1 yorum | WhatsApp'ta paylaş
  • AVX-512'nin vpternlogd komutu, üç girdinin herhangi bir bit düzeyindeki Boolean mantığını 8 bitlik bir immediate değerle seçip tek seferde çalıştıran bir SIMD komutudur
  • Kilit nokta, karmaşık mantık ifadelerini ezberlemek değil; #imm8 değerini üç girdi A/B/C'nin 8 olası durumu için bir lookup table olarak görmektir
  • 1985 tarihli Amiga blitter da üç bitmap kaynağı ve 8 bitlik bir minterm ile aynı şekilde mantıksal birleşimleri belirliyordu; masked sprite için sıkça 0xE2 kullanılıyordu
  • Sonuç sütunundaki 8 biti aşağıdan yukarı okuyunca immediate değer elde edildiği için, “üç girdiden tam olarak ikisi 1” gibi bir koşul bile doğrudan 0x68 olarak oluşturulabilir
  • Intel belgelerindeki vpternlogd örneği ile Amiga demoscene'de yaygın olan 0xE2 kesişiyor; modern SIMD komutları ile retro grafik donanımı aynı tasarım sezgisini paylaşıyor

AVX-512'nin vpternlogd komutu

  • vpternlogd, AVX-512 ISA tasarım tanıtım materyallerinde dikkat çeken bir bit düzeyinde üçlü mantık komutudur
  • Üç girdi A, B ve C alır ve herhangi bir Boolean mantığını tek komutta ifade edebilir
    • Örnek: (NOT A) OR ((NOT B) XOR (C AND A))
  • Girdiler 512 bitlik register olabilir; bu da karmaşık mantığın 512 bitin tamamına aynı anda uygulanmasını sağlar
  • foo_and_a_or_not_b gibi özel amaçlı komutları sürekli eklemek yerine, tek bir esnek komut ve 8 bitlik immediate ile çok sayıda mantık işlemi yapılır
VPTERNLOGD r0, r1, r3, #imm8
  • #imm8, hangi bit mantığı fonksiyonunun uygulanacağını belirler
  • Pek çok doküman immediate değerin yalnızca “belirli bir ikili fonksiyonu belirlediğini” söyler; bu yüzden gerçek hesaplama yöntemini sezgisel olarak kavramak zordur

Amiga blitter ve minterm

  • 1980'lerin bilgisayarlarında grafik işleme için custom chip kullanmak yaygındı
  • Commodore Amiga 500'ün blitter birimi, bitmap grafikleri bir konumdan başka bir konuma taşırken mantıksal işlemler uyguluyordu
  • En fazla üç bitmap kaynağını ele alıyor ve bunlar arasındaki mantıksal işlem 8 bitlik bir değer olan minterm ile belirtiliyordu
  • Üç kaynak ve 8 bitlik bir değerle mantıksal birleşimi seçmesi bakımından vpternlogd ile aynı yapıya sahiptir
  • Pek çok Amiga programcısı minterm hesaplamasını doğrudan anlamaktan ziyade sık kullanılan değerleri yeniden kullanıyordu
    • Buffer temizlemek için 0x00
    • Masked sprite çizmek için 0xE2
  • 1989 tarihli “Amiga Hardware Reference Manual”, minterm hesabını kafa karıştırıcı sembollerle anlattığı için o dönemki demo geliştiricilerine pek yardımcı olmuyordu

8 bitlik değeri lookup table olarak hesaplamak

  • #imm8 ya da minterm, mantık operatörlerinin bir birleşimi olarak değil, 8 öğeli bir lookup table olarak görülebilir
  • Üç girdi A, B ve C'nin her biri 0 ya da 1 olduğundan olası birleşim sayısı 8'dir
  • İstenen sonucu doğrudan dördüncü sütuna yazmak yeterlidir
A B C İstenen sonuç
0 0 0 ?
0 0 1 ?
0 1 0 ?
0 1 1 ?
1 0 0 ?
1 0 1 ?
1 1 0 ?
1 1 1 ?
  • Örneğin üç girdiden yalnızca tam iki tanesi 1 olduğunda sonucu 1 yapmak istiyorsanız, dördüncü sütunu bu koşula göre doldurursunuz
  • Ortaya çıkan sonuç sütununun 8 biti aşağıdan yukarı okununca 01101000, yani 0x68 elde edilir
  • Dolayısıyla 0x68 fonksiyonu, üç girdiden tam iki tanesi 1 olduğunda sonucu 1 yapar
  • Aynı yöntemle üç kaynak arasındaki herhangi bir mantık fonksiyonu için gerekli #imm8 değeri elde edilebilir

Masked sprite için 0xE2

  • Amiga'da çok yaygın minterm değerlerinden biri 0xE2'dir
  • Bu değer, masked 2D sprite render ederken sıkça kullanılır
    • A: sprite bitmap
    • B: sprite mask
    • C: background
  • Koşul, basit program mantığıyla ifade edilebilir
    • Maske pikseli B ayarlıysa sonuç sprite A olur
    • Maske pikseli B ayarlı değilse sonuç background C olur
A B C İstenen sonuç
0 0 0 0
0 0 1 1
0 1 0 0
0 1 1 0
1 0 0 0
1 0 1 1
1 1 0 1
1 1 1 1
  • Sonuç sütunu aşağıdan yukarı okununca 11100010, yani 0xE2 elde edilir
  • 0xE2, Amiga demoscene kültüründe çok yaygın bir minterm değeridir

Intel belgeleriyle tesadüfi bağlantı

1 yorum

 
GN⁺ 2024-10-07
Hacker News görüşleri
  • Hesaplamak istediğiniz ifadeden immediate değeri elde etmenin basit bir yolu var. Örneğin (NOT A) OR ((NOT B) XOR (C AND A)) hesaplamak istiyorsanız, ~_MM_TERNLOG_A | (~_MM_TERNLOG_B ^ (_MM_TERNLOG_C & _MM_TERNLOG_A)) şeklinde yazabilirsiniz
    Bu, kelimenin tam anlamıyla hesaplamak istediğiniz ifadedir ve gcc ile clang'ın intrinsic header'larında tanımlı _MM_TERNLOG_A/B/C sabitlerinden immediate olarak değerlendirilir: typedef enum { _MM_TERNLOG_A = 0xF0, _MM_TERNLOG_B = 0xCC, _MM_TERNLOG_C = 0xAA } _MM_TERNLOG_ENUM;
    MSVC'de ise bunu kendiniz tanımlayabilirsiniz

    • Daha az sihirli görünmesi için ikilik olarak yazabilirsiniz: A = 0b11110000, B = 0b11001100, C = 0b10101010
    • Amiga kılavuzu, çarpımların toplamı standart biçimine göre normalize etmeyi öneriyor
  • Başlığı görünce önce bu komutun düzgün çalışmadığı anlamına geldiğini sanmıştım. Asıl yazı ise sadece nasıl çalıştığını anlatıyor

    • Buradaki “busted” ifadesini, Intel çalışanlarının Amiga hayranı olduğunun ortaya çıkarılması anlamında yorumladım. Yazarın ana dili olan Fransızcadan İngilizceye geçerken bir şeyler kaybolmuş gibi duruyor
  • Ergenlik yıllarımda donanım kılavuzundaki o sayfaya “CRAP!” yazmadım ama anlamaya çalışmak için gerçekten çok uzun süre baktım
    Sonunda neredeyse herkes gibi Bobs ve basit kopyalama için BLTCON0'ı bulup kullandım ve o kısmı görmezden geldim
    Yine de birkaç yıl sonra üniversitede hesaplamalı mantık dersinden A+ aldım; belki de o travmanın biraz faydası olmuştur

  • Başlık hakkında konuşmak gerekirse, “ternary logic” normalde üç doğruluk değerine sahip mantık anlamına gelir. Ama bu yazı, üç giriş alan tüm ikili mantık kapılarını işleyen bir derleyici komutunu ele alıyor

    • x86 komutunun adı ternlog, intrinsic'in adı da ternarylogic, yani biraz talihsiz olsa da başlık uygun
      Ayrıca bitwise zaten bir ölçüde bunu “üç değerli mantık”tan ayırıyor ve ternary, üç giriş anlamında da oldukça sık kullanılıyor. a ? b : c de yaygın olarak ternary operator diye anılıyor; üstelik ternlog bu üçlü işleci taklit edebiliyor ve yazı da tam olarak bundan bahsediyor
    • Bu, “üç değerli mantık komutu”ndan çok “üç girdili mantık komutu” gibi
    • Üç doğruluk değerine sahip mantığın ne olduğunu bilmiyorum. Belki ternary yerine trinary düşünmüşsünüzdür
      C++, JavaScript ve Python açısından (a < b) ? 5 : 2 biçimindeki ternary expression en yaygın kullanım gibi görünüyor. https://www.programiz.com/cpp-programming/ternary-operator
      Her durumda hangi varsayımı yaparsanız yapın çok da önemli değil. Sözcüklerin ve ifadelerin birden fazla anlamı olur; ternary de üç parçalı anlamına geldiği için burada da uyuyor
    • Buradaki ternary o anlamda değil
      C'de + iki girdi aldığı için binary operator'dür, ?: ise üç girdi aldığı için ternary operator'dür. C'de tek örneği olduğu için genelde “the ternary operator” denir, yoksa özünde özel bir yanı yoktur
      vpternlogd, üç girdi alan tüm bit düzeyindeki ternary operator'ları gerçekleştirir
    • Ben de bu kısmı kafa karıştırıcı buldum. Ama “üç terimli ikili ifadeyi değerlendirme” gibi bir ad da daha az özlü olurdu
  • Windows'taki BitBlt işlevine benziyor olabilir mi diye düşündüm. En azından Windows 3.1 zamanından beri var gibiydi ve op parametresiyle kaynak, hedef ve maskenin nasıl birleştirileceği belirleniyordu
    Girdilerden bağımsız olarak siyah üreten BLACKNESS, kaynağı hedefe kopyalayan COPY gibi kod adları olduğunu hatırlıyorum. BLACKNESS ve WHITENESS kulağa bir şekilde şiirsel geliyordu
    Petzold'da okuduğumu hatırladığım kadarıyla bu yazılımla uygulanıyordu, ama çağrı sırasında opcode işlevin içinde özel assembly'ye çevrildiği için Windows işletim sistemindeki nadir self-modifying code örneklerinden biriydi

    • Evet. BitBlt başlangıçta ikili işlemleri ters Polonya gösterimiyle saklayan karmaşık 16 bitlik “operation code”lar kullanıyordu
      Sonra Amiga'daki gibi aynı bilgiyi 1 bayta sığdıran bir “operation index” eklendi; bu daha kısa ve daha zarif. Günümüzde her raster operation code hem operation index'i hem de operation code'u içerdiğinden kodlama yinelenmiş durumda. https://devblogs.microsoft.com/oldnewthing/20180528-00/?p=98...
  • FPGA'nın rastgele mantık fonksiyonlarını lookup table olarak gerçekleştirme biçimine benziyor

    • Temelde CPU, GPU ve FPGA'nın hepsi hesaplamanın benzer evrimleşmiş biçimlerine yakınsıyor. Farklı optimizasyon alanlarına sahip olsalar da aynı yetenekleri açığa çıkarıyorlar
    • Tüm mantık bellekle gerçekleştirilebilir ve tüm bellek de bir tür geri besleme yapısına sahip mantıkla gerçekleştirilebilir
      Ancak FPGA'lar ya da bu yazıdaki komut gibi özel amaçlı durumlar dışında bu genelde tercih edilmez. Yüksek hızlı register'lar ve statik RAM bazen mantıkla yapılır, ama kapılar yerine doğrudan transistörlerle yapmak daha yaygındır
    • Büyük ölçüde doğru, ama tamamen değil. Actel/Microsemi küçük multiplexer ve gate tree yapıları kullanıyor
    • 74181 arithmetic logic unit de bunu yapıyor
  • https://www.sandpile.org sitesine gidip 3 baytlık opcode sayfasında https://www.sandpile.org/x86/opc_3.htm VPTERNLOG öğesini ararsanız, Intel'in geçmişte planlamış gibi göründüğü bayt/word masking varyantı AVX512BITALG2'yi de görebilirsiniz
    Ayrıca Ib operandındaki 256 olası durumun tamamını içeren üçlü mantık tablosu sayfasına da bağlanıyor: https://www.sandpile.org/x86/ternlog.htm

  • Dokümantasyon örneğinde E2 fonksiyonunun seçilmesinin nedeni, bunun üç girişli Boolean fonksiyonları arasında neredeyse en temel ve standart mux olması olabilir: B ise A, değilse C
    Bu evrensel bir fonksiyondur; seçmek için ille de Amiga hayranı olmak gerekmez. Tabii gerçekten hayran olmuş da olabilirler

  • Bit düzeyindeki işlemlerin bir tamsayı içinde kodlandığı başka bir örnek de Win32'nin GDI ROP code'larıdır: https://learn.microsoft.com/en-us/windows/win32/gdi/ternary-...

  • Resmî bir Amiga donanım kılavuzum yoktu; onun yerine “Mapping the Amiga” kitabına bakıyordum. Aynı şeyleri biraz daha uzun anlatarak açıklıyordu
    O sırada hangi minterm'leri kullandığımı hatırlamıyorum ama bu kitaba bakarak shadebobs, bobs ve XOR 3D çizgi çizimi gibi şeyleri bir şekilde yaptığımı sanıyorum
    Mapping the Amiga'daki ilgili sayfa: https://archive.org/details/1993-thomson-randy-rhett-anderso...