C ++ 26'daki yenilikler: Paralel Veri Türleri (SIMD)

Adanali

Active member
C ++ 26'daki yenilikler: Paralel Veri Türleri (SIMD)


  1. C ++ 26'daki yenilikler: Paralel Veri Türleri (SIMD)

C ++ 'da, SIMD kütüphanesi, veri paralelliğinin açık temini ve daha verimli SIMD erişimi için verilerin yapılandırılması için 26 taşınabilir tip sunar. Yeni kütüphaneyi ayrıntılı olarak ele almadan önce, SIMD'ye (tek eğitim, daha fazla veri) kısaca bazı genel yorumlar göndermek istiyorum.






Rainer Grimm




Rainer Grimm yıllardır yazılım mimarı, ekip ve eğitim müdürü olarak çalıştı. C ++ programlama dilleri, Python ve Haskell hakkında makaleler yazmayı seviyor, ancak uzman konferanslarla konuşmayı da seviyor. Modern C ++ blogunda, C ++ tutkusuyla yoğun bir şekilde ilgileniyor.







SIMD – Tek Eğitim, Daha Fazla Veri


Vektörleştirme, modern işlemcilerin kontrol hızının SIMD uzantılarını (tek eğitim, daha fazla veri) ifade eder. SIMD, işlemcinin farklı verilere paralel olarak bir işlem uygulamasını sağlar.

Basit bir örnek: Paralel olarak bir algoritma gerçekleştiriliyorsa ve vektör, CPU ve SIMD komutlarının operasyonel desteği de dahil olmak üzere birçok faktöre bağlıdır. Aynı zamanda derleyiciye ve kodu doldurmak için kullanılan optimizasyon derecesine bağlıdır.



// SIMD.cpp

const int SIZE= 8;

int vec[]={1,2,3,4,5,6,7,8};
int res[SIZE]={0,};

int main(){
for (int i= 0; i < SIZE; ++i) {
res= vec+5; // (1)
}
}


Riga 1, küçük programdaki anahtar çizgidir. Explorer derleyicisi sayesinde, maksimum optimizasyon (-O3) olan ve olmayan CLANG 3.6 için montajın kontrollerini oluşturmak oldukça kolaydır.



Optimizasyon olmadan




Meclis komutlarıyla oynadığım zamanın uzun süredir olmasına rağmen, her şeyin ardışık hale getirileceği açıktır:









(Resim: Rainer Grimm)



Maksimum optimizasyon ile


Maksimum optimizasyon kullanarak, farklı veri kayıtlarına paralel olarak gerçekleştirilen komutlar alıyorum:









(Resim: Rainer Grimm)



Yer değiştirme işlemi (movdqa) ve ek ameliyat (paddd) Özel kayıtlar kullanın xmm0 VE xmm1. Her iki kayıt da 128 bit genişliğe sahip SSE SSE kaydıdır. Böylece 4 ints aynı anda geliştirilebilir. SSE, SIMD uzantılarının akışı anlamına gelir. Ne yazık ki, vektör komutları güçlü bir şekilde kullanılan mimariye bağlıdır. Ne kontroller ne de kayıt genişlikleri eşit değildir.

Modern Intel mimarileri genellikle AVX2 ve hatta AVX-512'yi destekler. Bu, 256 veya 512 bitlik işlemlere izin verir. Yani 8 veya 16 ints paralel olarak işlenebilir. AVX gelişmiş vektör uzantısını temsil eder.

Burası tam olarak kitapçı verilerinin yeni paralel verileri türlerinin devreye girdiği ve vektör komutlarına tek tip bir arayüz sunduğu yerdir.

Paralel veri türleri (SIMD)


Yeni kütüphane ile uğraşmadan önce bazı tanımlara ihtiyaç vardır. Bu tanımlar P1928R15 teklifini ifade eder. Toplamda, yeni kütüphane altı teklif içermektedir.





CPP SIMD




(Resim: Rainer Grimm)



Vectorize türlerinin miktarı, her tür ganzpachtätzt standardını, tasarım türlerini ve türlerini içerir float VE double. Ayrıca, onlar std::float16_t,, std::float32_t VE std::float64_t Vektör türleri tanımlanmışsa.

Paralel veriler terimi, sınıf modellerinin etkinleştirilen tüm uzmanlıklarını ifade eder basic_simd VE basic_simd_mask. Paralel veri nesnesi, verilerin paralel türünden bir nesnedir.

Paralel bir veri türü, altta yatan bir vektör türünün bir veya daha fazla öğesinden oluşur ve bu bir tür öğe olarak tanımlanır. Element sayısı, her veri paralel türü için bir sabittir ve bu tür genişlik olarak adlandırılır. Verilere paralel bir türdeki elemanlar, −1 genişliğinde 0 ile gösterilir.

Bir çalışma öğesi, bir veya daha fazla paralel veri nesnesinin öğelerine belirli bir işlem uygular. Bu uygulamaların her biri başkaları açısından sıralı değildir. Bir INARE çalışma öğesi, paralel bir veri nesnesinin her bir öğesi için Aralık olmayan bir işlem kullanan bir çalışma öğesidir. Çalışma öğesi, verilerle paralel olan iki nesnenin karşılık gelen öğelerinde ikili işlem kullanan bir çalışma öğesidir.

Çok fazla teoriden sonra, şimdi küçük bir örnek göstermek istiyorum. P1928R15 teklifinin yazarı Matthias Kretz'den geliyor. CPPCCC 2023'teki sunumunun örneği bir işlevi göstermektedir. fbir taşıyıcıyı kabul eden ve unsurlarını meme değerleri üzerinde tasvir eden:



void f(std::vector<float>& data) {
using floatv = std::simd<float>;
for (auto it = data.begin(); it < data.end(); it += floatv::size()) {
floatv v(it);
v = std::sin(v);
v.copy_to(it);
}
}


İşlev f Referans olarak şamandıra (veri) taşıyıcısını alır. Tanımlamak floatv Simd Floats Taşıyıcısı gibi std::simd<float>. f Vektör boyunca bloklar halinde, her blok SIMD taşıyıcısının boyutunda.

Her blok için aşağıdakiler geçerlidir:

  • Bloğu bir SIMD taşıyıcıya davet edin (floatv v(it);).
  • Sinüs fonksiyonu aynı zamanda SIMD taşıyıcısındaki tüm unsurlarla karşılaşır (v = std::sin(v);).
  • Sonuçları orijinal taşıyıcıya yazın (v.copy_to(it);).
P0350R4 teklifi C ++ 26'da uygulandığında SIMD talimatlarının tedavisi özellikle zarif hale gelir. Örneğin SIMD, bu nedenle algoritmalarda yeni bir yürütme politikası olarak kullanılabilir:



void f(std::vector<float>& data) {
std::for_each(std::execution::simd, data.begin(), data.end(), [](auto& v) {
v = std::sin(v);
});
}


Sırada ne var?


Bir sonraki makalemde yeni SIMD kütüphanesine daha yakından bakacağım.


(harita)




Ne yazık ki, bu bağlantı artık geçerli değil.

Boşa harcanan eşyalara olan bağlantılar, 7 günlük daha büyükse veya çok sık çağrılmışsa gerçekleşmez.


Bu makaleyi okumak için bir Haberler+ paketine ihtiyacınız var. Şimdi yükümlülük olmadan bir hafta deneyin – yükümlülük olmadan!
 
Üst