“Vektörizasyon” nedir?


190

Birkaç kez, bu terim matlab, fortran ... başka biriyle karşılaştım ... ama bunun ne anlama geldiğini ve ne anlama geldiğini hiç açıklamadım. Burada soruyorum, vektörizasyon nedir ve örneğin "bir döngü vektörleştirilir" ne anlama geliyor?


1
@geoffspear bağlantı taşındı görünüyor en.wikipedia.org/wiki/Array_programming
Kod Sevdiğim

Yanıtlar:


225

Birçok CPU'da aynı işlemi iki, dört veya daha fazla veri parçasına aynı anda uygulayan "vektör" veya "SIMD" komut setleri bulunur. Modern x86 çiplerinin SSE talimatları vardır, birçok PPC çipinin "Altivec" talimatları vardır ve hatta bazı ARM çiplerinin NEON adlı bir vektör talimat seti vardır.

"Vektörleştirme" (basitleştirilmiş) bir döngüyü yeniden yazma işlemidir, böylece bir dizinin tek bir elemanını N kez işlemek yerine, dizinin 4 elemanını aynı anda N / 4 kez işler (diyelim).

(4'ü seçtim çünkü modern donanımın doğrudan desteklemesi en muhtemel olan şeydir; "vektörleştirme" terimi, döngüyü tamamen soyutlayabileceğiniz ve öğeler yerine diziler üzerinde çalışmayı tanımlayabileceğiniz daha üst düzey bir yazılım dönüşümünü tanımlamak için de kullanılır. bunlardan oluşur)


Vektörleştirme ve döngü çözme arasındaki fark: İki dizinin öğelerini ekleyen ve sonuçları üçüncü bir diziye depolayan aşağıdaki çok basit döngüyü göz önünde bulundurun.

for (int i=0; i<16; ++i)
    C[i] = A[i] + B[i];

Bu döngünün açılması, bunu aşağıdaki gibi bir şeye dönüştürür:

for (int i=0; i<16; i+=4) {
    C[i]   = A[i]   + B[i];
    C[i+1] = A[i+1] + B[i+1];
    C[i+2] = A[i+2] + B[i+2];
    C[i+3] = A[i+3] + B[i+3];
}

Öte yandan, vektörize etmek, böyle bir şey üretir:

for (int i=0; i<16; i+=4)
    addFourThingsAtOnceAndStoreResult(&C[i], &A[i], &B[i]);

"AddFourThingsAtOnceAndStoreResult", derleyicinizin vektör talimatlarını belirtmek için kullandığı gerçek (ler) için bir yer tutucudur. Bazı derleyicilerin, genellikle bir derleme seçeneği ile etkinleştirilebilen çok basit döngüleri otomatik olarak vektörleştirebildiğini unutmayın . Daha karmaşık algoritmalar hala iyi vektör kodu oluşturmak için programcıdan yardım gerektirir.


11
Bu ve loop unwinding / unrolling arasındaki fark nedir?
Jeremy Powell

1
Bir derleyicinin açılmamış döngüyü otomatik olarak vektörleştirmek için daha kolay bir işi olacağı doğru değil mi?
Nikos Athanasiou

@NikosAthanasiou: Mantıklı, ancak genellikle bir derleyici her iki döngüyü de otomatikleştirebilmelidir, çünkü ikisi de oldukça basittir.
Stephen Canon

1
@StephenCanon bazı çizgilerin vektörlenip çizilmediğini nasıl kontrol edebilirim? Eğer biri objdump kullanırsa, objdump çıktısında ne arardı?
user1823664

3
@Shuklaswag: vektörleştirme, derleyicilerin sizin için yapabileceği bir şeydir, ancak aynı zamanda programcıların açıkça kendileri de yaptığı bir şeydir. İşletim sistemi dahil değildir.
Stephen Canon

32

Vektörizasyon, bir skaler programı bir vektör programına dönüştürmek için kullanılan terimdir. Vectorized programlar tek bir komuttan birden fazla işlem gerçekleştirebilirken, skaler sadece bir anda işlenen çiftlerinde çalışabilir.

Gönderen wikipedia :

Skaler yaklaşım:

for (i = 0; i < 1024; i++)
{
   C[i] = A[i]*B[i];
}

Vektörize yaklaşım:

for (i = 0; i < 1024; i+=4)
{
   C[i:i+3] = A[i:i+3]*B[i:i+3];
}

bu aslında Skaler yaklaşımla aynı değil mi? Sözdizimi ve döngü ilerlemeniz farklıdır, ancak altında hala 4 kez çarpıyorsunuz. Ama bir şekilde CPU'nun Vectorization adı verilen bir hile yapan talimatları olması muhtemelen daha hızlı olacaktır.
mskw

Görünüşe göre burada kendi sorumu cevaplayacağım. Karşılaştırıcı bunu gördüğünde vektörleştirme yaklaşımındaki sözdizimi, onu vektörleri çoğaltan optimize edilmiş CPU talimatlarına dönüştürecektir. SIMD gibi.
mskw

10

Tek bir adımda sayıların bir listesi - ya da "vektörü" üzerinde tek bir matematiksel işlem yapma yeteneğini ifade eder. Bunu Fortran ile sık sık görüyorsunuz çünkü bu, vektörize aritmetiğin ilk ortaya çıktığı süper hesaplama ile ilişkili bilimsel hesaplama ile ilişkilidir. Günümüzde neredeyse tüm masaüstü CPU'lar Intel'in SSE'si gibi teknolojiler aracılığıyla bir çeşit vektörize aritmetik sunuyor. GPU'lar ayrıca bir çeşit vektörize aritmetik sunar.


7

Vektörleştirme , büyük veri parçalarının verimli bir şekilde işlenmesi gereken bilimsel hesaplamada büyük ölçüde kullanılır.

Gerçek programlama uygulamasında, NUMPY'de (başkalarından emin değilim) kullanıldığını biliyorum.

Numpy (python'da bilimsel hesaplama için paket), dizileri işlemek için dahili python seçenekleriyle yapılırsa genellikle daha yavaş olan n boyutlu dizinin hızlı manipülasyonu için vektörleştirmeyi kullanır .

açıklama ton orada olmasına rağmen, Burada ne var Vektoriyal gibi tanımlandığı numpy BELGELER SAYFA

Vectorization, kodda herhangi bir açık döngü, indeksleme vb. Bulunmadığını açıklar - bu şeyler, elbette, optimize edilmiş, önceden derlenmiş C kodunda sadece “perde arkasında” gerçekleşir. Vectorized kodun birçok avantajı vardır:

  1. vectorized kod daha özlü ve okunması daha kolay

  2. daha az kod satırı genellikle daha az hata anlamına gelir

  3. kod standart matematiksel gösterime daha çok benzemektedir (tipik olarak matematiksel yapıları doğru şekilde kodlamayı kolaylaştırır)

  4. vektörizasyon daha “Pythonic” koduyla sonuçlanır. Vektörizasyon olmasaydı, kodumuz verimsiz ve okunması zor döngülerle doluydu.


4

Vektörleştirme, basit bir ifadeyle, algoritmayı işlemcilerde SIMD talimatlarını kullanabilmesi için optimize etmek anlamına gelir.

AVX, AVX2 ve AVX512, bir komutta birden çok veri üzerinde aynı işlemi gerçekleştiren komut kümeleridir (intel). örneğin. AVX512, aynı anda 16 tamsayı değeri (4 bayt) üzerinde çalışabileceğiniz anlamına gelir. Bunun anlamı, 16 tamsayı vektörünüz varsa ve her bir tamsayıda bu değeri iki katına çıkarmak ve sonra ona 10 eklemek istiyorsanız. Değerleri genel kayda [a, b, c] 16 kez yükleyebilir ve aynı işlemi yapabilir veya 16 değeri SIMD kayıtlarına [xmm, ymm] yükleyerek ve işlemi bir kez gerçekleştirerek aynı işlemi gerçekleştirebilirsiniz. Bu, vektör verilerinin hesaplanmasını hızlandırır.

Vektörleştirmede bunu, SIMD işlemlerini gerçekleştirebilmemiz ve programı hızlandırabilmemiz için verilerimizi yeniden modelleyerek avantajımız için kullanıyoruz.

Vektörleşmeyle ilgili tek sorun koşulların ele alınmasıdır. Çünkü koşullar yürütme akışını dallar. Bu maskeleme ile ele alınabilir. Durumu aritmetik bir işlem olarak modelleyerek. Örneğin. 100'den büyükse değere 10 eklemek istiyorsak, ikisini de yapabiliriz.

if(x[i] > 100) x[i] += 10; // this will branch execution flow.

ya da koşulu bir şart vektörü yaratarak aritmetik işleme modelleyebiliriz,

c[i] = x[i] > 100; // storing the condition on masking vector
x[i] = x[i] + (c[i] & 10) // using mask

bu çok önemsiz bir örnek olsa da ... c, değerine bağlı olarak ikili işlemi gerçekleştirmek için kullandığımız maskeleme vektörüdür. Bu, yürütme akışının dallanmasını önler ve vektörleştirmeyi sağlar.

Vektörleşme, Paralelleştirme kadar önemlidir. Bu nedenle, onu mümkün olduğunca kullanmalıyız. Günümüzün tüm işlemcilerinin yoğun bilgi işlem iş yükleri için SIMD talimatları vardır. Kodumuzu, vektörleştirme kullanarak bu SIMD talimatlarını kullanacak şekilde optimize edebiliriz, bu, kodumuzu modern işlemcilerde bulunan birden fazla çekirdek üzerinde çalışacak şekilde paralelleştirmeye benzer.

Ben pragmas kullanarak kodu vectorize sağlayan OpenMP söz ile ayrılmak istiyorum. İyi bir başlangıç ​​noktası olarak görüyorum. Aynı şey OpenACC için de söylenebilir.


0

Intel insanlar tarafından anlaşılması kolay olduğunu düşünüyorum.

Vektörleştirme, bir algoritmanın bir seferde tek bir değer üzerinde çalışmasını bir seferde bir değer kümesi üzerinde çalışmasına dönüştürme işlemidir . Modern CPU'lar, çoklu verilere (SIMD) tek bir komutun uygulandığı vektör işlemleri için doğrudan destek sağlar.

Örneğin, 512 bit yazmaçlı bir CPU 16 adet 32 ​​bit tek duyarlıklı ve tek bir hesaplama yapabilir.

Tek seferde tek bir komutu yürütmekten 16 kat daha hızlı. Bunu iş parçacığı ve çok çekirdekli işlemcilerle birleştirerek büyüklük performans kazanımlarına yol açar.

Bağlantı https://software.intel.com/tr-tr/articles/vectorization-a-key-tool-to-improve-performance-on-modern-cpus

Java'da bunun 2020 Jdk 15'e veya 2021'de JDK 16'da geç olarak dahil edilmesi için bir seçenek vardır.

https://bugs.openjdk.java.net/browse/JDK-8201271


-4

Yukarıdaki iki cevaba bakınız. Sadece vektörleşme yapmak istemesinin nedeninin, bu işlemlerin süper bilgisayarlar ve çoklu işlemciler tarafından kolayca paraellde gerçekleştirilebildiğini ve büyük bir performans kazancı sağladığını eklemek istedim. Tek işlemcili bilgisayarlarda performans kazancı olmayacaktır.


12
"Tek işlemcili bilgisayarlarda performans kazancı olmayacak": doğru değil. Modern işlemcilerin çoğu, kullanıldığında önemli bir hız kazandırabilen vektörleştirme (stephentyrone tarafından adlandırılan SSE, Altivec vb.) İçin donanım desteğine (sınırlı) sahiptir.
sleske

teşekkürler, paralelleştirmenin o düzeyde de yapılabileceğini unuttum.
Larry Watanabe
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.