Kurmak
Varlıklar (davranışları olmayan saf veri olan) bir dizi özniteliklere sahip olabilen bir varlık bileşeni mimarisine sahibim ve bu veriler üzerinde hareket eden varlık mantığını çalıştıran sistemler var. Temel olarak, biraz sahte kodda:
Entity
{
id;
map<id_type, Attribute> attributes;
}
System
{
update();
vector<Entity> entities;
}
Tüm varlıklar boyunca sabit bir oranda hareket eden bir sistem,
MovementSystem extends System
{
update()
{
for each entity in entities
position = entity.attributes["position"];
position += vec3(1,1,1);
}
}
Aslında, update () 'i olabildiğince verimli bir şekilde paralelleştirmeye çalışıyorum. Bu, tüm sistemleri paralel olarak çalıştırarak veya bir sistemin her güncellemesine () birkaç bileşen vererek farklı iş parçacıklarının aynı sistemin güncellemesini yürütebilmesi için, ancak bu sisteme kayıtlı farklı bir varlık alt kümesi için yapılabilir.
Sorun
Gösterilen MovementSystem durumunda, paralelleştirme önemsizdir. Varlıklar birbirine bağlı olmadığından ve paylaşılan verileri değiştirmediğinden, tüm varlıkları paralel olarak taşıyabiliriz.
Bununla birlikte, bu sistemler bazen varlıkların birbirleriyle, bazen aynı sistem içinde, ancak çoğu zaman birbirine bağlı farklı sistemler arasında etkileşim kurmasını (veri okuma / yazma) gerektirir.
Örneğin, bir fizik sisteminde bazen varlıklar birbirleriyle etkileşime girebilir. İki nesne çarpışır, konumları, hızları ve diğer nitelikleri onlardan okunur, güncellenir ve daha sonra güncellenen özellikler her iki varlığa geri yazılır.
Ve motordaki oluşturma sistemi varlıkları oluşturmaya başlamadan önce, ilgili tüm özniteliklerin olması gereken şey olduğundan emin olmak için diğer sistemlerin yürütmeyi tamamlamasını beklemek zorundadır.
Bunu körü körüne paralel hale getirmeye çalışırsak, farklı sistemlerin verileri aynı anda okuyabileceği ve değiştirebileceği klasik yarış koşullarına yol açacaktır.
İdeal olarak, tüm sistemlerin aynı verileri değiştiren diğer sistemler hakkında endişelenmeksizin ve programcıya, bu sistemleri manuel olarak (bazen mümkün bile olmayabilir).
Temel bir uygulamada, bu sadece kritik bölümlere tüm verileri okuyup yazarak (mutekslerle korunarak) sağlanabilir. Ancak bu, büyük miktarda çalışma zamanı yükünü indükler ve muhtemelen performansa duyarlı uygulamalar için uygun değildir.
Çözüm?
Benim düşünceme göre, olası bir çözüm, verilerin okunması / güncellenmesi ve yazılmasının ayrıldığı bir sistem olacaktır, böylece tek bir pahalı aşamada, sistemler sadece verileri okur ve hesaplamak için gerekeni hesaplar, bir şekilde sonuçları önbelleğe alır ve sonra hepsini yazar değiştirilen veri ayrı bir yazma işleminde hedef varlıklara geri döndürülür. Tüm sistemler, çerçevenin başında olduğu durumda ve daha sonra çerçevenin bitiminden önce, tüm sistemler güncelleştirmeyi bitirdiğinde, önbelleğe alınan tüm farklı sonuçların bulunduğu bir seri yazma geçişi gerçekleşir. sistemler tekrarlanır ve hedef varlıklara geri yazılır.
Bu, sonuçta önbelleğe almanın ve yazma geçişinin maliyetini (hem çalışma zamanı performansı hem de kod ek yükü açısından) aşacak kadar büyük olabileceği (belki de yanlış?) Fikrine dayanır.
Soru
Optimum performans elde etmek için böyle bir sistem nasıl uygulanabilir? Böyle bir sistemin uygulama ayrıntıları nelerdir ve bu çözümü kullanmak isteyen bir Varlık Bileşen sisteminin önkoşulları nelerdir?