Ben bir gezegensel bilim araştırmacısıyım ve üzerinde çalıştığım bir proje , Satürn'ün halkalarının N -body simülasyonları. Bu özel çalışmanın amacı, parçacıkların kendi yerçekimleri altında toplandıklarını izlemek ve kümelerdeki toplam kütlenin hücre içindeki tüm parçacıkların ortalama hızına karşı ölçülmesidir. Bunun , Satürn yaz gündönümü sırasında Cassini uzay aracı tarafından, büyük yapıların neredeyse kenar halkalarına gölge düşürdüğü gözlemlendiğinde yapılan bazı gözlemleri açıklayıp anlayamayacağını anlamaya çalışıyoruz . Aşağıda, verilen herhangi bir zaman testinin neye benzediğinin bir ekran görüntüsü bulunmaktadır. (Her parçacık 2 m çapındadır ve simülasyon hücresinin kendisi yaklaşık 700 m çapındadır.)
Kullandığım kod zaten her hızda ortalama hızı tükürüyor. Yapmam gereken, kümelerdeki parçacıkların kütlesini belirlemek için bir yol bulmak ve aralarındaki sokak parçacıklarını DEĞİL. Her parçacığın pozisyonunu, kütlesini, büyüklüğünü vb. Biliyorum, ama diyorum ki, 30.000-40.000 parçacıklarının 102.000-105.000 ile birlikte insan gözünün açık olduğu bir ipi oluşturduğunu bilmiyorum.
Bu nedenle, yazmam gereken algoritmanın, tüm parçacık konumlarından geçecek, hangi parçacıkların kümelere ait olduğunu anlayacak ve daha sonra kitle. Hücrenin üzerindeki her şeye karşı "her" yığın / iplikçik için yapabilseydim harika olurdu, ama aslında onları ayırmak için buna ihtiyacım olduğunu düşünmüyorum .
Ben düşünüyordum tek şey bir çeşit yapıyordu N 2 Ben en yakın 100 parçacıklar, belirli bir mesafe içinde idi sonra partikül a bir parçası olarak kabul edileceğini, her parçacığın arasında diyelim ki, eğer mesafe hesaplamak istiyorum mesafe hesaplama küme. Ama bu oldukça özensiz görünüyor ve ben CS millet ve programcılar daha zarif bir çözüm biliyor olabilir umuyordum?
Benim Çözeltisi ile Düzenlendi: Benim yaptığım en yakın komşu / kümelenme yaklaşımının bir tür almak ve kirli hızlı-n-yapmak oldu N 2 ilk uygulaması. Bu nedenle, her parçacığı alın, diğer tüm parçacıklara olan mesafeyi hesaplayın ve bir kümedeki eşik değeri d mesafede N parçacıkları olup olmadığıydı ( maalesef priori olarak ayarlanması gereken iki parametre , ancak bazılarının söylediği gibi) yanıtlar / yorumlar, bunlardan bazılarına sahip olmaktan kurtulmayacaktım).
Daha sonra mesafeleri sıralayarak değil, sadece bir sipariş N araması yaparak hızlandırdım ve d içindeki parçacıklar için bir sayaç arttırdım ve bu 6 faktörü kadar hızlandırdı. Sonra bir aptal programcı ağacı ekledim (çünkü biliyorum ağaç kodlarıyla ilgili hiçbir şeyin yanında). Simülasyon hücresini , ana ızgara hücreyle aynı hizaya geldiğinde , bir ızgara x ve y ile yarım kaydırılır ve diğer ikisi de kaydırılır, belirli sayıda ızgaraya (ızgara boyutu ≈7 d olduğunda en iyi sonuçlar ) bölerim 1/4 inç ± x ve ± y . Kod daha sonra parçacıkları ızgaralara böler, daha sonra her bir parçacık N'nin sadece o hücredeki diğer parçacıklara göre hesaplanmış mesafeleri olması gerekir.
Teorik olarak, bu gerçek bir ağaç olsaydı, N 2 hızlarının aksine N * log ( N ) siparişini almalıyım . İkisi arasında bir yere girdim, burada 50.000 parçacık alt kümesi için hızda 17 kat artış sağladım ve 150.000 parçacık hücresi için hızda 38 kat artış sağladım. Birincisi için 12 saniye, ikincisi için 53 saniye, 500.000 parçacık hücresi için 460 saniye. Bunlar, kodun simülasyon 1 zaman aşımını çalıştırmanın ne kadar sürdüğü ile karşılaştırılabilir hızlardır, bu nedenle bu noktada mantıklıdır. Oh - ve tamamen yivli, bu yüzden atabildiğim kadar çok işlemci alacak.