Paralel Diziler ne zaman kullanılabilir?


14

Ben 'Paralel Diziler' veya Listeler dediğim kullanan kod (yeni kod) çalıştırıyorum. Yani ilgili veriler içeren ve dizideki konumlarına (dizinlerine) bağlı 2 dizi vardır.

Bunu kafa karıştırıcı ve her türlü hataya eğilimli olarak görüyorum. Normalde önerdiğim çözüm CompanyCompanyId ve CompanyName alanlarıyla adlandırılan bir nesne oluşturmaktır .

Çok gerçek bir örnek:

List<string> companyNames;
List<int> companyIds;

//...They get populated somewhere and we then process

for(var i=0; i<companyNames.Count; i++)
{
    UpdateCompanyName(companyIds[i],companyNames[i]);
}

Bu paralel diziler kötü uygulama olarakgörülüyor ?


9
Sadece Fortran yazamadığınız hiçbir dilin icat edilmediğini kanıtlayın.
andy mango

3
Böyle bir şey yapmanın (oldukça önemli) önbellek yararları olabilir (bağlantılı listeler değil bitişik dizilere ihtiyacınız olsa da) ve bu "veri odaklı tasarım" ile ilgili oyun programlamasında biraz popüler olmuştur. Ancak, bu sizin durumunuz için geçerli görünmemektedir. Performans açısından kritik kod oluşturuyormuşsunuz gibi görünmüyor.
Derek Elkins SE

2
@DerekElkins ... Yorumunuzun bunu Fortran koduyla karşılaştıran birini takip etmesi ilginç. Fortran'ın ilk sürümlerinde kullanıcı tanımlı yapılar için destek yoktu ve deyim eklendiğinde bile Fortran kodu, yapı dizileri değil birden çok özellik dizisi kullanıyor. Ve bu, Fortran'ın genellikle en hızlı dil olarak kabul edilmesinin nedeninin bir parçası olarak kabul edilir.
Jules

3
Bu soruya teğetsel bir düşünce: birçok işlevsel dil bu tür listelerle çalışmayı aktif olarak teşvik eder. Genellikle zip olarak adlandırılan ve onları bir grup listesine dönüştüren bir işlevi vardır. Kodunuz C # gibi görünüyor. C # 'ın son sürümü birinci sınıf tuples için destek ekledi. Bu nedenle, listelerinizi sizin için otomatik olarak yararlı bir yapıya koyabilecek bir yere bir zip işlevi ekleyip eklemediklerini merak ediyorum.
Jules

4
Bazen, iki diziyi kasıtlı olarak kullanmanın nedenleri vardır, ancak tüm vakaların% 99'unda bunu gördüm, bunun tek nedeni, orijinal yazarın kucaklayan bir veri yapısı tanıtmak için tembelliğiydi.
Doc Brown

Yanıtlar:


23

Birisinin parrel dizilerini kullanmasının bazı nedenleri şunlardır:

  1. Sınıfları veya yapıları desteklemeyen bir dilde
  2. Tek tek iş parçacıkları sütunlardan yalnızca birini değiştirirken iş parçacığı kilitlemesini önlemek için
  3. Kalıcılık yöntemi bunları ayrı depolanmaya zorladığında ve bunları yeniden oluşturuyorsanız.
  4. Yapılar doluysa daha az bellek tüketebilirler. (C # 'daki bu veri türleri için geçerli değildir)
  5. CPU önbelleğini verimli kullanmak için verilerin bir kısmının birbirine yakın tutulması gerektiğinde (yukarıdaki kodda yardımcı olmaz).
  6. Tek Yönlü Çoklu Veri (SIMD) op kodlarının kullanımı. (bu kod veya dizeler için geçerli değildir)

Bu durumda bunu yapmak için zorlayıcı bir neden görmüyorum ... ve yukarıdakilerin hepsinde muhtemelen daha iyi seçenekler var veya üst düzey bir dilde çok kullanışlı değiller.


3
Yapılar doluysa daha az bellek tüketebilirler. Akıllıca tahsis edilen birkaç büyük dizi, bir dizi yapıdan daha az bellek tüketebilir.
Frank Hileman

4
4. CPU önbelleğini verimli kullanmak için verilerin bazı bölümlerinin birbirine yakın tutulması gerektiğinde. (Nadir durumlarda
gereklidir

@Frank Hileman, Whilie TheCatWhisperer'in cevabının tamamen doğru olduğunu düşünüyorum, yorumunuz aslında bu yaklaşımı seçmek için en iyi neden. Bellek tüketimi kritikse, yapıların dolgusu üzerindeki bellek ek yükü, özellikle de büyük sayılar varsa, önemli olabilir.
Vladimir Stokic


Re (2), Nasıl? Tek bir dizi dizilimi ve alan başına kilitli bir program yazabildiğim gibi, birden çok diziye ve dizi başına bir kilide sahip olabildiğince kolayca yazabiliyorum.
Solomon Slow

7

Ben oldum paralel diziler kullanmaktan suçlu . Bazen yapıya giriyorsunuz, nasıl soyutlanacağını düşünmek istemiyorsunuz. Soyutlamanın yeniden düzenlenmesi biraz daha zor olabilir, bu yüzden gerçekten neye ihtiyacınız olduğunu kanıtlayana kadar doğrudan başlatmak istemezsiniz.

Bu noktada detayları soyutlamak için yeniden düzenleme yapmayı düşünmeye değer. Genellikle yapmak istemediğim en büyük neden, iyi bir isim düşünmenin zor olduğu ortaya çıkıyor.

Paralel dizileri soyutlamak için iyi bir yol görürseniz, bunu her seferinde yapın. Ama onlara dokunmayı reddederek kendinizi felç etmeyin. Bazen biraz kirli kod, büyük koda giden en iyi basamaktır.


6

Bu kalıp bazen Dizilerin Yapısı olarak da adlandırılır ( Yapı Dizisi yerine) ve kodu vektörlerken son derece kullanışlıdır. Tek bir yapı üzerinde çalışan bir hesaplama yazmak ve bitlerini vektörlemek yerine, hesaplamayı SSE intrinsics hariç normalde yaptığınız gibi bir yerine 4 yapı üzerinde çalışacak şekilde yazarsınız. Bu genellikle daha kolay ve neredeyse her zaman daha hızlıdır. SoA formatı bunu çok doğal kılıyor. SSE bellek işlemlerini daha hızlı hale getiren hizalamayı da geliştirir.


Evet, bu yaklaşım GPU'da makine öğrenimi yaparken kullanılır. Birçok ayrı örneğin alanlarını ayırmak, her alanın tüm değerlerini ayrı bir tensöre paketlemek ve tahminlerin bir listesini oluşturmak için bu tensörleri toplu olarak hesaplanacak şekilde aktarmak gelenekseldir.
Monica
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.