2015-04-30 15 views
5

ben şöyle bir yapıya sahiptir:En hızlı Olası Struct-of-Diziler Dizi-of-the Yapılar Dönüşüm

struct SoA 
{ 
    int arr1[COUNT]; 
    int arr2[COUNT]; 
}; 

Ve böyle bakmak istiyorum:

struct AoS 
{ 
    int arr1_data; 
    int arr2_data; 
}; 

std::vector<AoS> points; 

olarak olabildiğince çabuk. Sipariş korunmalıdır.

tek tek her AoS nesneyi oluşturup bunu yapmanın en hızlı şekilde geri iterek veya daha hızlı bir seçenek yoktur mı?

SoA before; 
std::vector<AoS> after; 

for (int i = 0; i < COUNT; i++) 
    points.push_back(AoS(after.arr1[i], after.arr2[i])); 

StackOverflow'daki soruları ile ilgili SoA/AoS vardır, ama en hızlı olası dönüşüm biri ilgili bulamadı. Yapısal paketleme farklılıkları nedeniyle, verileri bir formattan diğerine kopyalamaktan kaçınmanın bir yolunu göremiyorum, ancak birisinin bana sadece verileri farklı şekilde referans göstermenin ve bir kopyadan kaçınmanın bir yolu olduğunu söyleyebilmeyi umuyorum. çözümlerde Kapalı

özellikle teşvik etti.

+0

Bellekte farklı bir düzenlemeye sahip olduğundan, "verileri farklı şekilde referans" edebileceğinizi sanmıyorum. – immibis

+0

Ve yine de onları eklemeniz/zorlamanız gerekecektir, aksi takdirde 'vektör'ünüz geçerli durumda olmaz. okuma veya doğrusal bellek yazma ve bu örnek modelin bozabilir çözümleyecek bir sürü yaparken farklı verilere başvurulması aslında bir kopyasını yaparak daha hızlı olmayabilir –

+1

Not olduğunu ... RAM önbelleğe fazla cache sürü neden onların en etkili altındadır ve bu nedenle daha yavaş yürütme. (ya da belki de değil, ama önemli olan şey her iki yolu ölçmek ve sezgileriniz gerçekle eşleşmediğinde şaşırmaya hazır olmaktır) –

cevap

5

İkili SoA düzeni ve AoS[]/std::vector<AoS> farklıdır, bu nedenle kopyalama işleminden olmadan birbirlerine dönüşümü için bir yol gerçekten yoktur. Sahip

Kod optimal oldukça yakın - bir gelişme belki elemanlarının beklenen sayı ile vektör önceden tahsis etmek. Alternatif olarak, hem tam öğe hem de özellik başına başlatma işlemini yapılandırarak ham diziyi deneyin. Değişiklikler dikkatli bir şekilde ölçülmelidir (kesinlikle beklediğiniz dizi boyutları ile tam olarak optimize edilmiş yapı kullanarak ölçün) ve kodun doğruluğu/doğruluğuna karşı ağırlıklandırılmalıdır. Eğer tam bir ikili düzen gerekmiyorsa

farklı şekilde mevcut verileri ifşa edeceği çift özel sınıflar oluşturarak sözdizimi görünümlü benzer başarmak mümkün olabilir (eğer vektör kullandığınız olarak bu durumda görünmektedir). Bu tamamen kopyalanmayı engeller. Sen

(O dizinde ayrı alanlar için erişimcileri açığa SOA ve dizinin örneğine referece ile başlatıldı) ve "eleman" türü (SoA örneğinin üzerinde indeksleme/yineleme sağlamak) "dizi" türü gerekir

Kodun kaba taslakları (yineleyiciler ekleyin ...):

class AoS_Element 
{ 
    SoA& soa; 
    int index; 
public: 
    AoS_Element(SoA& soa, int index) ... 
    int arr1_data() { return soa.arr1[index];} 
    int arr2_data() { return soa.arr2[index];} 
} 

class AoS 
{ 
    SoA& soa; 
public: 
    AoS(SoA& _soa):soa(_soa){} 
    AoS_Element operator[](int index) { return AoS_Element(soa, index);} 
} 
+0

Bahsettiğiniz "dizi" türünü genişletebilir misiniz? Doğru, ikili temsilin amacı buradaki amaç değil, sadece öğelere etkin erişim. Özel bir yineleyici kullanmamayı düşünmemiştim –

+0

@ConnorLawson Çok kaba bir örnek ekledim (muhtemelen derleme bile yapamayacağım ... umarım sözcüklerden daha iyi ne anlama geldiğini gösterir). –

+0

'std :: vector' içeriğinin düz bir eski diziye özdeş ikili düzeni vardır. –

İlgili konular