SIMD programlama kod tabanının bakım maliyeti


14

Soru:

Yazılım endüstrisinin fikir birliği, temiz ve basit kodun, kod tabanının ve sahibi olan kuruluşun uzun vadeli uygulanabilirliği için temel olduğu yönündedir. Bu özellikler daha düşük bakım maliyetlerine ve kod tabanının devam etme olasılığının artmasına neden olur.

Ancak, SIMD kodu genel uygulama kodundan farklıdır ve özellikle SIMD koduna uygulanan temiz ve basit kod konusunda benzer bir fikir birliği olup olmadığını bilmek istiyorum.


Sorumun arka planı.

Çeşitli görüntü işleme ve analiz görevleri için bol miktarda SIMD (tek komutlu, çoklu veri) kodu yazıyorum. Son zamanlarda, bu işlevlerin az bir kısmını bir mimariden (SSE2) diğerine (ARM NEON) taşımak zorunda kaldım.

Kod, büzülme ile sarılmış yazılım için yazılmıştır, bu nedenle MATLAB gibi sınırsız yeniden dağıtım hakları olmadan özel dillere bağlı olamaz.

Tipik kod yapısına bir örnek:

  • Kullanma OpenCV 'matrisi tipi ( Mat) tüm bellek için, tampon ve kullanım süresi yönetimi.
  • Girdi bağımsız değişkenlerinin boyutunu (boyutlarını) kontrol ettikten sonra, her piksel satırının başlangıç ​​adresine işaretçiler alınır.
  • Piksel sayısı ve her giriş matrisinden her piksel satırının başlangıç ​​adresleri bazı düşük seviyeli C ++ işlevlerine geçirilir.
  • Bu düşük seviyeli C ++ işlevleri , ham işaretçi adreslerinden yükleme ve ham işaretçi adreslerine kaydetme gibi SIMD intrinsics ( Intel Mimarisi ve ARM NEON için ) kullanır.
  • Bu düşük seviyeli C ++ işlevlerinin özellikleri:
    • Sadece tek boyutlu (hafızada ardışık)
    • Bellek ayırma işlemleriyle ilgilenmez.
      (Geçiciler dahil her ayırma işlemi, OpenCV olanakları kullanılarak dış kodla gerçekleştirilir.)
    • Sembollerin isim uzunlukları aralığı (intrinsics, değişken isimler, vb.) Kabaca 10-20 karakterdir ve bu oldukça fazladır.
      (Tekno-gevezelik gibi okur.)
    • Derleyiciler doğru olan kod ayrıştırma oldukça arabası çünkü SIMD değişkenlerin Tekrar önerilmez değil stil kodlama "tek atama" ile yazılmış.
      (Birkaç derleyici hata raporu verdim.)

SIMD programlamanın hangi yönleri tartışmanın genel durumdan farklı olmasına neden olur? Veya SIMD neden farklı?

İlk geliştirme maliyeti açısından

  • İyi bir performansa sahip C ++ SIMD kodunun ilk geliştirme maliyetinin, rasgele yazılmış C ++ koduna kıyasla yaklaşık 10x - 100x (geniş bir marjla) olduğu bilinmektedir .
  • Performans ile okunabilir / temiz kod arasında seçim yapma cevaplarında belirtildiği gibi ? , çoğu kod (rasgele yazılmış kod ve SIMD kodu dahil) başlangıçta ne temiz ne de hızlıdır .
  • Kod performansındaki (hem skaler hem de SIMD kodunda) evrimsel iyileştirmeler önerilmez (çünkü bir tür yazılım yeniden çalışması olarak görülür ) ve maliyet ve fayda izlenmez.

Eğilim açısından
(örneğin Pareto prensibi, yani 80-20 kuralı )

  • Görüntü işleme bir yazılım sisteminin sadece% 20'sini (hem kod boyutu hem de işlevsellik) içeriyor olsa bile, görüntü işleme nispeten yavaştır (harcanan CPU zamanının yüzdesi olarak bakıldığında) ve% 80'den fazla zaman alır.
    • Bunun nedeni veri boyutu efektidir: Tipik bir görüntü boyutu megabayt olarak ölçülürken, görüntü olmayan verilerin tipik boyutu kilobayt olarak ölçülür.
  • Görüntü işleme kodu içinde, bir SIMD programcısı, C ++ kodundaki döngü yapısını tanımlayarak sıcak noktaları içeren% 20 kodunu otomatik olarak tanıyacak şekilde eğitilir. Dolayısıyla, bir SIMD programcısının bakış açısından, "önemli olan kodun"% 100'ü performans darboğazıdır.
  • Genellikle bir görüntü işleme sisteminde, birden fazla sıcak nokta bulunur ve karşılaştırılabilir oranlarda zaman alır. Örneğin, her biri toplam süreyi alan 5 sıcak nokta (% 20,% 18,% 16,% 14,% 12) olabilir. Yüksek performans artışı elde etmek için, tüm sıcak noktaların SIMD'de yeniden yazılması gerekir.
    • Bu balon patlatma kuralı olarak özetlenir : bir balon iki kez patlatılamaz.
    • Diyelim ki 5 tane balon var. Onları yok etmenin tek yolu onları tek tek patlatmaktır.
    • İlk balon patlatıldıktan sonra, kalan 4 balon artık toplam yürütme süresinin daha yüksek bir yüzdesini içermektedir.
    • Daha fazla kazanç elde etmek için, daha sonra başka bir balonu patlatmak gerekir.
      (Bu kadar hiçe sayarak optimizasyon 80-20 üstünlüğü: İyi bir ekonomik sonuç aldı edilmiştir düşük-asılı meyve% 20 sonra elde edilebilir.)

Okunabilirlik ve bakım açısından

  • SIMD kodunun okunması zordur.

    • Adlandırma, kapsülleme, sabit doğruluk (ve yan etkileri açık hale getirme), işlev ayrışması vb. Gibi her yazılım mühendisliği en iyi uygulamasını izlese bile bu doğrudur.
    • Bu, deneyimli SIMD programcıları için bile geçerlidir.
  • Optimal SIMD kodu, eşdeğer C ++ prototip koduna kıyasla çok kıvrılmıştır (açıklamaya bakınız) .

    • SIMD kodunu bükmenin birçok yolu vardır, ancak bu tür 10 denemeden yalnızca biri kabul edilebilir derecede hızlı sonuçlara ulaşacaktır.
    • (Yani, yüksek geliştirme maliyetini haklı çıkarmak için 4x-10x performans kazançları arasında. Uygulamada daha yüksek kazançlar gözlemlenmiştir.)

(Not)
Bu, MIT Halide projesinin ana tezidir- makalenin başlık kelimesini alıntılamak:

"Görüntü işleme boru hatlarının kolay optimizasyonu için zamanlamalardan algoritmaları ayırmak"

İleri uygulanabilirlik açısından

  • SIMD kodu kesinlikle tek bir mimariye bağlıdır. Her yeni mimari (veya SIMD kayıtlarının her genişletilmesi) bir yeniden yazma gerektirir.
  • Yazılım geliştirmenin çoğundan farklı olarak, her SIMD kodu parçası genellikle hiçbir zaman değişmeyen tek bir amaç için yazılır.
    (Diğer mimarilere taşıma hariç.)
  • Bazı mimariler mükemmel geriye dönük uyumluluk sağlar (Intel); önemsiz bir miktarda (ARM AArch64 değiştirilmesiyle bir düşüş kısa vtblolan vtblq), ancak yeterli olan bir kod derlemek için başarısız olmasına neden.

Beceri ve eğitim açısından

  • Yeni bir programcıyı SIMD kodu yazmak ve korumak için uygun şekilde eğitmek için hangi bilgi ön koşullarının gerekli olduğu açık değildir.
  • Okulda SIMD programlamasını öğrenen üniversite mezunları bunu pratik bir kariyer izi olarak görmezden gelir ve reddederler.
  • Demontaj okuma ve düşük seviye performans profili, yüksek performanslı SIMD kodu yazmak için iki temel beceri olarak belirtilir. Ancak, programcılara bu iki beceri konusunda nasıl sistematik bir şekilde eğitim verileceği belirsizdir.
  • Modern CPU mimarisi (ders kitaplarında öğretilenlerden önemli ölçüde farklılaşır) eğitimi daha da zorlaştırır.

Doğruluk ve kusurla ilgili maliyetler açısından

  • Tek bir SIMD işleme fonksiyonu, şu şekilde doğruluk sağlayabilecek kadar uyumludur:
    • Resmi yöntemlerin uygulanması (kalem ve kağıt ile) ve
    • Çıkış tamsayı aralıklarını doğrulama (prototip kodu ile ve çalışma zamanı dışında gerçekleştirilir) .
  • Bununla birlikte, doğrulama işlemi çok maliyetlidir (SIMD kodunun zaten pahalı geliştirme maliyetini üçe katlayan), kod incelemesine% 100 zaman ve prototip model kontrolüne% 100 zaman harcar.
  • Bir hata bir şekilde bu doğrulama işleminden geçmeyi başarırsa, şüpheli kusurlu işlevi değiştirmek (yeniden yazmak) dışında "onarmak" (düzeltmek) neredeyse imkansızdır.
  • SIMD kodu, C ++ derleyicisindeki kusurların körlenmesinden muzdariptir (kod üreteci optimize edilir).
    • C ++ ifade şablonları kullanılarak oluşturulan SIMD kodu da derleyicinin kusurlarından büyük ölçüde etkilenir.

Yıkıcı yenilikler açısından

  • Akademiden birçok çözüm önerilmiştir, ancak çok azı yaygın ticari kullanım görmektedir.

    • MIT Halide
    • Stanford Karanlık Oda
    • NT2 (Sayısal Şablon Araç Kutusu) ve ilgili Boost.SIMD
  • Yaygın ticari kullanımı olan kütüphaneler, SIMD özellikli değildir.

    • Açık kaynaklı kütüphaneler SIMD için ılık görünüyor.
      • Son zamanlarda, 2.4.9 sürümünden itibaren çok sayıda OpenCV API fonksiyonunun profilini oluşturduktan sonra bu ilk elden gözlemim var.
      • Profillediğim diğer birçok görüntü işleme kütüphanesi de SIMD'yi yoğun bir şekilde kullanmıyor veya gerçek sıcak noktaları kaçırıyor.
    • Ticari kütüphaneler SIMD'den tamamen uzak görünüyor.
      • Bazı durumlarda, daha önceki bir sürümde SIMD için optimize edilmiş kodu daha sonraki bir sürümde SIMD olmayan koda döndüren görüntü işleme kitaplıklarının bile ciddi performans gerilemelerine neden olduğunu gördüm.
        (Satıcının yanıtı, derleyici hatalarından kaçınmak gerektiğidir.)

Bu Programcının sorusu: Düşük gecikme kodunun bazen "çirkin" olması gerekir mi? ilişkilidir ve daha önce bu soruya birkaç yıl önce bakış açımı açıklamak için bir cevap yazdım.

Ancak, bu cevap hemen hemen "erken optimizasyon" bakış açısına, yani şu bakış açısına "yatıştırmak" tır:

  • Tüm optimizasyonlar tanım gereği erken (veya doğaları gereği kısa vadeli ) ve
  • Uzun vadeli faydası olan tek optimizasyon basitliğe yöneliktir.

Ancak bu bakış açıları bu ACM makalesinde tartışılmaktadır .


Tüm bunlar sormamı sağlıyor:
SIMD kodu genel uygulama kodundan farklı ve SIMD kodu için temiz ve basit kodun değeri konusunda benzer bir endüstri mutabakatı olup olmadığını bilmek istiyorum.


2
Performans gereksinimleri var mı? SIMD kullanmadan performans gereksinimlerinizi karşılayabilir misiniz? Değilse soru tartışmalıdır.
Charles E. Grant

4
Bu bir soru için çok uzun, büyük olasılıkla iyi bir parça soruyu etkili bir şekilde cevaplamak için bir girişim ve hatta bir cevap için uzun (kısmen makul cevapların çoğundan daha fazla yönlere değdiği için).

3
Optimize edilmiş alternatiflere ek olarak hem temiz / basit / yavaş kod (kavramın ilk kanıtı ve daha sonraki dokümantasyon amaçları için) var. Bu, anlaşılmasını kolaylaştırır (insanlar temiz / basit / yavaş kodu okuyabildiğinden) ve doğrulaması kolaydır (optimize edilmiş sürümü temiz / basit / yavaş sürümle manuel olarak ve birim testleriyle karşılaştırarak)
Brendan

2
@Brendan Benzer bir projede bulundum ve basit / yavaş kodla test yaklaşımını kullandım. Dikkate değer bir seçenek olsa da, sınırlamaları da vardır. İlk olarak, performans farkı engelleyici olabilir: optimize edilmemiş kod kullanan testler saat ... gün sürebilir. İkincisi, görüntü işleme için, optimize edilmiş kod biraz farklı sonuçlar ürettiğinde, bit-bit karşılaştırmanın işe yaramayacağı ortaya çıkabilir - böylece ef kök ortalama kare farkı
gnat

2
Bu soruyu konu dışı olarak kapatmak için oy kullanıyorum çünkü yardım merkezinde açıklandığı gibi kavramsal bir programlama sorunu değil .
durron597

Yanıtlar:


6

Kendim için çok fazla SIMD kodu yazmadım, ancak birkaç yıl önce bir çok montajcı kodu yazdım. SIMD intrinsics kullanan AFAIK temelde montajcı programlamasıdır ve tüm sorunuz sadece "SIMD" kelimesini "montaj" kelimesiyle değiştirerek yeniden ifade edilebilir. Örneğin, daha önce bahsettiğiniz noktalar, örneğin

  • kodun geliştirilmesi "yüksek seviye kodundan" 10x ila 100x daha fazla zaman alır

  • belirli bir mimariye bağlı

  • kod asla "temiz" değildir ve yeniden düzenlenmesi kolay değildir

  • yazmak ve bakımını yapmak için uzmanlara ihtiyacınız var

  • hata ayıklama ve bakım zor, gerçekten zor gelişiyor

hiçbir şekilde SIMD'ye "özel" değildir - bu noktalar her türlü montaj dili için geçerlidir ve hepsi "endüstri konsensüsüdür". Ve yazılım endüstrisindeki sonuç da montajcı ile hemen hemen aynıdır:

  • gerekmiyorsa yazmayın - mümkün olan her yerde üst düzey bir dil kullanın ve derleyicilerin zor işi yapmasına izin verin

  • Derleyiciler yeterli değilse, en azından bazı kitaplıklarda "düşük seviye" bölümleri kapsülleyin, ancak kodu programınızın her tarafına yaymaktan kaçının

  • "kendi kendini belgeleyen" montajcı veya SIMD kodu yazmak neredeyse imkansız olduğundan, bunu birçok belge ile dengelemeye çalışın.

Tabii ki, "klasik" montaj veya makine kodu ile durum gerçekten de bir fark var: bugün, modern derleyiciler genellikle elle yazılmış montajcı kodundan daha iyi optimize edilmiş yüksek seviyeli bir dilde yüksek kaliteli makine kodu üretir. Bugün popüler olan SIMD mimarileri için, mevcut derleyicilerin kalitesi AFAIK'in çok altındadır - ve belki de asla ulaşmayacaktır, çünkü otomatik vektörleştirme hala bilimsel bir araştırma konusudur. Örneğin, bir derleyici ve bir insan arasındaki optimizasyon farklarını açıklayan bu makaleye bakın ve iyi SIMD derleyicileri oluşturmanın çok zor olabileceği fikrini verin.

Sorunuzda daha önce açıkladığınız gibi, mevcut en son kütüphanelerde de kalite sorunu var. Bu yüzden umut edebileceğimiz en iyi IMHO, önümüzdeki yıllarda derleyicilerin ve kütüphanelerin kalitesinin artacağı, belki de SIMD donanımının daha "derleyici dostu" olmak için değişmesi gerekecek, belki de daha kolay vektörleştirmeyi destekleyen özel programlama dilleri (Halide gibi) iki kez bahsetmiştin) daha popüler olacak (bu zaten Fortran'ın gücü değil miydi?). Wikipedia'ya göre , SIMD yaklaşık 15 ila 20 yıl önce "kitlesel bir ürün" oldu (ve Halide belgeleri doğru yorumladığımda 3 yaşından küçüktür). Bunu olgunlaşmak için gereken "klasik" montaj dili için zaman derleyicileri ile karşılaştırın. Göre bu Wikipedia makalesindederleyiciler insan uzmanlarının performansını (paralel olmayan makine kodu üretiminde) aşana kadar yaklaşık 30 yıl (~ 1970'den 1990'ların sonuna kadar) sürdü. Bu nedenle, SIMD özellikli derleyiciler için de aynen gerçekleşene kadar 10 ila 15 yıl daha beklememiz gerekebilir.


Wikipedia makalesini okuduğumda , düşük seviyede optimize edilmiş kodun "hatırlanması gereken çok sayıda teknik ayrıntı nedeniyle kullanımı zor olduğu" konusunda genel bir fikir birliği var gibi görünüyor
gnat

@gnat: evet, kesinlikle, ama sanırım bunu cevabıma eklersem, OP'nin daha önce bahsettiği bir düzine başka şey daha çok uzun soruda.
Doc Brown

katılıyorum, cevabınızdaki analiz olduğu gibi yeterince iyi görünüyor, bu referansın "aşırı yükleme" riski taşıyacağını ekleyerek
gnat

4

Kuruluşum bu sorunla başa çıktı. Ürünlerimiz video alanında, ancak yazdığımız kodun çoğu, hareketsiz görüntüler için de çalışacak görüntü işleme.

Kendi derleyicimizi yazarak sorunu "çözdük" (veya belki de "ilgilenmiş"). Bu ilk başta göründüğü kadar çılgın değil. Kısıtlı bir girdi kümesi var. Tüm kodların çoğunlukla RGBA görüntüleri olmak üzere görüntüler üzerinde çalıştığını biliyoruz. Giriş ve çıkış arabelleklerinin hiçbir zaman üst üste binememesi gibi bazı kısıtlamalar oluşturduk, böylece işaretçi takma adı yok. Bunun gibi şeyler.

Daha sonra kodumuzu OpenGL Gölgeleme Dili'ne (glsl) yazıyoruz. Skaler kod, SSE, SSE2, SSE3, AVX, Neon ve tabii ki gerçek glsl için derlenir. Yeni bir platformu desteklememiz gerektiğinde, derleyiciyi o platformun çıkış koduna güncelleyeceğiz.

Ayrıca önbellek tutarlılığını ve bunun gibi şeyleri iyileştirmek için görüntüleri döşeriz. Ancak görüntü işlemeyi küçük bir çekirdeğe tutarak ve glsl (işaretçileri bile desteklemez) kullanarak kodu derlemenin karmaşıklığını büyük ölçüde azaltıyoruz.

Bu yaklaşım herkes için değildir ve kendi sorunları vardır (örneğin derleyicinin doğruluğunu sağlamanız gerekir). Ama bizim için gayet iyi işledi.


Bu 🔥🔥 geliyor! Sattığınız veya sunduğunuz bu ürün bağımsız mı? (Ayrıca, 'AVC' = AVX?)
Ahmed Fasih

Üzgünüm, evet, AVX demek istedim (bunu düzeltirim.). Şu anda derleyiciyi bağımsız bir ürün olarak satmıyoruz, ancak gelecekte olabilir.
user1118321

Şaka yok, bu gerçekten temiz görünüyor. Böyle gördüğüm en yakın şey, CUDA derleyicisinin hata ayıklama için CPU üzerinde çalışan “seri” programları nasıl yapabildiğiydi - bunun çok iş parçacıklı ve SIMD CPU kodu yazmak için bir yol haline getirilmesini umuyorduk, ancak ne yazık ki. Düşünebileceğim bir sonraki en yakın şey OpenCL'dir - millet OpenCL'yi değerlendirip GLSL'den herkese derleyicinizden daha düşük mü buldunuz?
Ahmed Fasih

1
Peki OpenCL başladığımızda yoktu, sanmıyorum. (Ya da öyleyse, oldukça yeniydi.) Yani denkleme gerçekten gelmedi.
user1118321

0

Daha üst düzey bir dil kullanmayı düşünüyorsanız çok fazla bakım yükü eklemiyor gibi görünüyor:

Vector<float> values = GetValues();
Vector<float> increment = GetIncrement();

// Perform addition as a vector operation:
List<float> result = (values + increment).ToList();

vs

List<float> values = GetValues();
List<float> increment = GetIncrement();

// Perform addition as a monadic sequence operation:
List<float> result = values.Zip(increment, (v, i) => v + i).ToList();

Tabii ki kütüphanenin sınırlamalarıyla yüzleşmek zorunda kalacaksınız, ancak kütüphaneyi kendiniz sürdürmeyeceksiniz. Bakım maliyeti ve performans kazancı arasında iyi bir denge olabilir.

http://blogs.msdn.com/b/dotnet/archive/2014/04/07/the-jit-finally-proposed-jit-and-simd-are-getting-married.aspx

http://blogs.msdn.com/b/dotnet/archive/2014/05/13/update-to-simd-support.aspx


okuduğuma göre, harici kütüphaneleri kullanma seçeneği zaten askerler tarafından araştırılmış ve ele alınmıştı: "Yaygın ticari kullanıma sahip kütüphaneler SIMD özellikli değil gibi görünüyor ..."
gnat

@gnat Ben aslında sadece üst düzey kurşun noktaları değil, tüm paragraf okudum ve poster herhangi bir genel amaçlı SIMD kütüphaneleri, sadece bilgisayar görme ve görüntü işleme olanlar bahsetmiyor. Soru başlığına yansıyan C ++ etiketi ve C ++ özgüllüğü olmamasına rağmen, üst düzey diller uygulamasının analizinin tamamen eksik olduğundan bahsetmiyoruz. Bu, sorumun birincil olarak değerlendirilmese de, değer katacağına ve insanları diğer seçeneklerden haberdar etmesine inanmamı sağlıyor.
Den

1
Anladığım kadarıyla, OP yaygın ticari kullanıma sahip çözümler olup olmadığını soruyor. İpucunu takdir etsem de (belki de lib'i burada bir proje için kullanabilirim), gördüğüm kadarıyla RyuJIT bir "yaygın kabul gören endüstri standardı" olmaktan çok uzak.
Doc Brown

@DocBrown belki, ama asıl sorusu daha genel olacak şekilde formüle edilmiştir: "... SIMD kodu için temiz ve basit kodun değeri konusunda endüstri konsensüsü ...". Hiç (resmi) bir fikir birliği olduğundan şüpheliyim, ancak daha yüksek seviyeli dillerin "normal" ve SIMD kodu arasındaki farkı azaltabileceğini, tıpkı C ++ montajı unutacağınız ve böylece bakım maliyetlerini azaltabileceğini söylüyorum.
Den

-1

Yakın zamanda SIMD programlama değil montaj programlama yaptım.

Intel gibi SIMD uyumlu bir derleyici kullanmayı düşünüyor musunuz? Mı için vektör A Guide Intel® C ++ Derleyiciler ile ilginç?

"Balon patlatma" gibi yorumlarınızın birçoğu bir derleyici kullanmanızı önerir (tek bir etkin noktanız yoksa fayda sağlamak için).


okumaya göre, bu yaklaşım asker tarafından denendi, bkz. derleyicide hatalar / kusurlar söz konusu
gnat

OP , aynı zamanda bu Programcılar'ın konusu olan Intel derleyicisini denemiş olup olmadıklarını söylemedi . Çoğu insan denemedi. Herkes için değil; ancak OP'nin işine / sorusuna uygun olabilir (daha düşük kodlama / tasarım / bakım maliyeti için daha iyi performans).
ChrisW

soruda okuduğum şey, askerin Intel ve diğer mimariler için derleyiciler hakkında farkında olduğunu gösteriyor: "Bazı mimariler mükemmel geriye dönük uyumluluk sağlıyor (Intel); bazıları kısa sürüyor ..."
gnat

Bu cümledeki "Intel", derleyici yazarı değil, çip tasarımcısı anlamına gelir.
ChrisW
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.