Veri odaklı tasarım nedir?


156

Bu makaleyi okuyordum ve bu adam veri odaklı tasarımda OOP ile karıştırmanın herkesden nasıl büyük fayda sağlayabileceği hakkında konuşmaya devam ediyor. Ancak hiçbir kod örneği göstermiyor.

Ben bu googled ve herhangi bir kod örnekleri, bunun ne olduğu hakkında herhangi bir gerçek bilgi bulamadık. Bu terime aşina olan ve bir örnek verebilecek olan var mı? Bu belki başka bir şey için farklı bir kelime midir?


7
Oyun geliştiricisindeki bu makale artık blog biçiminde okunabilir: gamesfromwithin.com/data-oriented-design
Edmundito

58
Siz hiç bir şeyi googlediniz, iyi bir hedeflenmiş SO sorusu buldunuz ve sonra yıllar önce bunu soran siz oldunuz mu?
ryeguy

1
İşte web üzerindeki DOD içeriğinin
toplamı

14
@ryeguy, bir sorum vardı, googled, hoş bir SO sorusu buldum ve sonra yıllar önce cevap verdiğimi fark ettim .
Michael Deardeuff

4
Bir şey aradım ve hoş bir SO sorusu buldum ve tahmin et ne oldu? Ne sordu ne de cevaplayan ben
değildim

Yanıtlar:


289

Her şeyden önce, bunu veri odaklı tasarımla karıştırmayın.

Veri Odaklı Tasarım anlayışım, verilerinizin verimli işleme için organize edilmesiyle ilgilidir. Özellikle önbellek özledikleri vb. İle ilgili olarak Veriye Dayalı Tasarım, verilerin program davranışlarınızın çoğunu kontrol etmesine izin vermekle ilgilidir ( Andrew Keith'in cevabı tarafından çok iyi tanımlanmıştır ).

Uygulamanızda renk, yarıçap, kabarıklık, konum vb. Özelliklere sahip top nesneleriniz olduğunu varsayalım.

Nesneye Yönelik Yaklaşım

OOP'ta topları şöyle tarif edersiniz:

class Ball {
  Point  position;
  Color  color;
  double radius;

  void draw();
};

Ve sonra böyle bir top koleksiyonu yaratacaksınız:

vector<Ball> balls;

Veri Odaklı Yaklaşım

Bununla birlikte, Veri Odaklı Tasarım'da kodu şöyle yazmanız daha olasıdır:

class Balls {
  vector<Point>  position;
  vector<Color>  color;
  vector<double> radius;

  void draw();
};

Gördüğünüz gibi artık bir Topu temsil eden tek bir birim yok. Top nesneleri yalnızca örtük olarak bulunur.

Bu, akıllıca birçok avantajı olabilir. Genellikle aynı anda birçok top üzerinde işlem yapmak isteriz. Donanım genellikle büyük sürekli bellek parçalarının verimli çalışmasını ister.

İkinci olarak, top özelliklerinin sadece bir kısmını etkileyen işlemler yapabilirsiniz. Örneğin, tüm topların renklerini çeşitli şekillerde birleştirirseniz, önbelleğinizin yalnızca renk bilgisi içermesini istersiniz. Ancak, tüm top özellikleri bir ünitede saklandığında, bir topun diğer tüm özelliklerini de çekersiniz. Onlara ihtiyacınız olmasa bile.

Önbellek Kullanımı Örneği

Her topun 64 bayt, bir noktanın 4 bayt aldığını varsayalım. Bir önbellek yuvası da 64 bayt alır. 10 topun konumunu güncellemek istersem, 10 * 64 = 640 bayt belleği önbelleğe almam ve 10 önbellek özlemi almam gerekiyor. Ancak topların pozisyonlarını ayrı birimler olarak çalıştırabilirsem, bu sadece 4 * 10 = 40 bayt alacaktır. Bu bir önbellek getirme uyuyor. Böylece sadece 10 topu güncellemek için sadece 1 önbellek özledim olsun. Bu sayılar keyfi - önbellek bloğunun daha büyük olduğunu düşünüyorum.

Ancak bellek düzeninin önbellek isabetlerine ve dolayısıyla performansa nasıl ciddi bir etkisi olabileceğini gösterir. Bu sadece CPU ve RAM hızı arasındaki fark arttıkça önem kazanacaktır.

Bellek nasıl düzenlenir

Top örneğimde, sorunu çok basitleştirdim, çünkü genellikle herhangi bir normal uygulama için birden fazla değişkene birlikte erişeceksiniz. Örneğin, konum ve yarıçap muhtemelen sık sık birlikte kullanılacaktır. O zaman yapınız şöyle olmalıdır:

class Body {
  Point  position;
  double radius;
};

class Balls {
  vector<Body>  bodies;
  vector<Color>  color;

  void draw();
};

Bunu yapmanızın nedeni, birlikte kullanılan veriler ayrı dizilere yerleştirilirse, önbellekteki aynı yuvalar için rekabet etme riski vardır. Böylece birini yüklemek diğerini dışarı atacaktır.

Bu nedenle Nesne Odaklı programlamaya kıyasla, yaptığınız sınıflar sorunun zihinsel modelinizdeki varlıklarla ilgili değildir. Veriler, veri kullanımına bağlı olarak toplandığından, sınıflarınıza Veri Odaklı Tasarımda vermek için her zaman mantıklı adlarınız olmaz.

İlişkisel veritabanları ile ilişkisi

Veri Odaklı Tasarımın arkasındaki düşünce, ilişkisel veritabanları hakkındaki düşüncelerinize çok benzer. İlişkisel bir veritabanını optimize etmek de önbelleğin daha verimli kullanılmasını içerebilir, ancak bu durumda önbellek CPU önbelleği değil, bellekteki sayfalardır. İyi bir veritabanı tasarımcısı da çok az sütun içeren bir tablo oluşturmak yerine, nadiren erişilen verileri ayrı bir tabloya ayırır. Ayrıca, bazı tabloları denormalize etmeyi seçebilir, böylece verilere diskteki birden çok konumdan erişilmesi gerekmez. Veri Odaklı Tasarımda olduğu gibi, bu seçimler veri erişim kalıplarının ne olduğuna ve performans darboğazının nerede olduğuna bakarak yapılır.


4
Bunun için teşekkürler, çok iyi açıkladın.
ryeguy

4
iyi dedi; Yine de sadece bir sorum var. Diyelim ki bir yapımız var struct balls {vector<vec3> pos; vector<vec3> velocity;}, her topun konumunu güncellemeyeceğiz, çünkü hız vektörü ve konum vektörü arasında ileri geri hareket edeceğiniz için aslında önbellek atıyor (evet, modern makineler ve önbellek çizgileri ve tüm bunlar, bu ayrıca sadece bir örnek)?
falstro

14
Olabilir. Ancak, tüm pos dizisinin aynı anda çekilmeyeceğini unutmayın. Sadece bir önbellek hattı ve bazı önceden getirme. Aynı şekilde hız ile. Bu yüzden birbirlerini çöpe atmaları için karşılık gelen pos ve vektör parçaları aynı önbellekle eşleşmelidir. Elbette bu olabilir, bu yüzden öneri birlikte kullanılan değişkenleri bir yapıda bir araya getirmektir. Yani örneğin hız ve poz bir vektörde, renk başka bir vektörde olur.
Erik Engheim

1
@roe Birlikte erişilen özellikleri birlikte gruplandırmalısınız. Özellikler arasında hiçbir bağımlılık olmamalıdır. Yani bu yapı daha iyi olurdu struct balls { vector<color> colors; vector<body> bodies; /* contains position and velocity */ }.
danijar

2
@danijar Açıklamayı önerilerinizle güncelledim. Bununla ilgili çok daha fazla şey söyleyebilirdim, ama bu gerçekten bir makaleye dönüşecek.
Erik Engheim

18

Mike Acton son zamanlarda Veri odaklı tasarım hakkında bir konuşma yaptı :

Bunun temel özeti şu olurdu: performans istiyorsanız, veri akışını düşünün, sizinle vidalama ve sabitleme için en uygun depolama katmanını bulun . Mike L2 önbellek özlüyor odaklanıyor, çünkü o gerçek zamanlı yapıyor, ama aynı şey veritabanları (disk okumaları) ve hatta Web (HTTP istekleri) için de geçerli olduğunu düşünüyorum. Sistem programlama yapmanın yararlı bir yolu olduğunu düşünüyorum.

Sizi algoritmalar ve zaman karmaşıklığı hakkında düşünmekten kurtarmaz, sadece dikkatinizi çılgın CS becerilerinizle hedeflemeniz gereken en pahalı çalışma türünü bulmaya odaklar.


14

Sadece Noel'in özellikle oyun geliştirmede karşılaştığımız bazı özel ihtiyaçlardan bahsettiğini belirtmek istiyorum. Gerçek zamanlı yumuşak simülasyon yapan diğer sektörlerin bundan fayda sağlayacağını düşünüyorum, ancak genel iş uygulamalarında belirgin bir iyileşme gösterecek bir teknik olması pek olası değildir. Bu kurulum, performansın her bir bitinin altta yatan donanımdan sıkılmasını sağlamak içindir.


Kabul. Veri odaklı tasarımın önemli olduğu diğer bazı alanlar şunlardır: yüksek bant genişliğine sahip cihazlar için donanım ve bellenim (örn. Ağ veya depolama); büyük ölçekli bilimsel hesaplama (örn. hava simülasyonu, protein katlama), sinyal işleme (örn. ses, görüntü, video), veri sıkıştırma. Bunlar, bazen daha tipik Bilgisayar Biliminden ayrı bir ana dal olarak sunulan "Hesaplamalı Bilim ve Mühendislik" kapsamına girer.
rwong

-3

Veri odaklı tasarım, uygulama mantığının prosedür algoritmaları yerine veri kümelerinden oluştuğu bir tasarımdır. Örneğin

usulsel yaklaşım.

int animation; // this value is the animation index

if(animation == 0)
   PerformMoveForward();
else if(animation == 1)
  PerformMoveBack();
.... // etc

veri tasarımı yaklaşımı

typedef struct
{
   int Index;
   void (*Perform)();
}AnimationIndice;

// build my animation dictionary
AnimationIndice AnimationIndices[] = 
  {
      { 0,PerformMoveForward }
      { 1,PerformMoveBack }
  }

// when its time to run, i use my dictionary to find my logic
int animation; // this value is the animation index
AnimationIndices[animation].Perform();

Bunun gibi veri tasarımları, uygulamanın mantığını oluşturmak için verilerin kullanımını teşvik eder. Özellikle animasyon veya başka bir faktöre dayanan binlerce mantık yoluna sahip olabilen video oyunlarında yönetmek daha kolaydır.


14
Bu aslında doğru değil. Veri odaklı tasarımı veri odaklı tasarımla karıştırıyorsunuz. Noel'in makalesini okuyana ve tamamen farklı bir şeyden bahsettiğini anlayana kadar aynı şeyi yaptım.
Erik Engheim

12
Ayrıca, Indice bir kelime değildir. "İndeks" ve "indeksler" ve hatta bazı "endeksler" de göz ardı edilir, ancak "indis" asla doğru değildir.
Baxissimo
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.