2012-08-17 39 views
9

Neredeyse çok büyük tamsayıları işleyen bir algoritma ile işim bitti (yaklaşık 100.000.000 değerine yükseltilen güç sırasıyla). Algoritmanın bellek yoğun olmadığı için bu, bir çift çekirdekli 16 çekirdekli sunucuda yeterli hafızaya sahip bir çift saat alır. Ben 4.BigInteger hesaplamaları hızlandırmak için GPU kullanma

algoritmasının özelliklerini önemli olmayan ancak bağlam için aşağıdaki bu tamsayılar ve algoritmanın bazı belirgin özellikleri üzerinde gerçekleştirilen operasyonların oldukça ayrıntılı bir liste olduğu .NET BigInteger sınıfı faydalanmak:

  • Toplama/Çıkarma.
  • Büyük sayıların küçük sayılar ile çarpımı.
  • Çok sayıda küçük sayılarla bölme (ör. 2).
  • Taban 2 Günlük.
  • Temel 2 Güç.
  • İki veya daha fazla büyük sayının karşılaştırması (Min/Maks).
  • Asal sayıların hiçbir katılımı yoktur.
  • Algoritma, bellek erişiminin performans isabeti, bazı akıllı, anında yapılan hesaplamalarinkinden daha fazla olduğu için, özellikle bellek yoğun olarak tasarlanmamıştır. Bununla birlikte, eğer bellek erişimi gelişirse, algoritma makul fayda sağlayabilir.

Ben mümkün olduğunca kod optimize ve profilleme şimdi sadece iki darboğazları gösterir: Bu tür büyük sayılar için üs 2 Log hesaplama

  • .
  • Bu sayılardaki önceden tanımlı ikili sayı örüntülerinin kontrol edilmesi. Bunun nedeni, BigInteger temelli verilere erişmenin tek yolunun, ilk önce yerinde işlemler yerine ToByteArray kullanmasıdır. Ayrıca, bayt boyutlu parçalar üzerinde işlem yapmak performansa yardımcı olmaz.

bellek erişimi ve Log operasyonları göz önüne alındığında, ben GPU'ları hakkında ve ben etkili işin bazı yükünü olup olamayacağını düşünmeye başladım. Kayan nokta işlemleri için optimize edilmiş olmaları dışında GPU'lar hakkında çok az şey biliyorum.

Soruma göre, GPU .NET gibi bir kitaplık kullanarak, GPU'da bu kadar büyük sayıları nasıl işleyebilirim? Böyle büyük sayılarda Log hesaplamak için bir şekilde kayan nokta optimizasyonlarını kullanabilir miyim?

Strateji oluşturmak için bir başlangıç ​​noktası mı arıyorsunuz?

+0

CUDAfy.NET'i kullanmayı düşündünüz mü? http://cudafy.codeplex.com/ (Aklınızdan çıkarmayın, bu NVIDIA'ya özeldir, bu yüzden sizin için yararlı olmayabilir) –

cevap

5

C# 'da GPU çalışması için etrafa bakıyorum ve Tidepowerd.com GPU.NET ve CUDAfy.NET'i düşünüyorum. Nvidia'ya özgü ve CUDAfy, en son kontrol ettiğimde mono (henüz) desteklemedi. Ancak ikisi de C# içinde GPU üzerinde çalışan makul derecede normal görünen bir kod için izin verir.

Ayrıca, bir 3 boyutlu parti kitaplığı kullanmayı düşündünüz mü? Açık kaynak kodlu birkaç tane de çok iyi BigInteger kütüphanesi var. GMP çok iyi ve özgürdür; http://gmplib.org/, en az bir C# sarmalayıcı (hangi deneyimim yok) var http://www.emilstefanov.net/Projects/GnuMpDotNet/

.NET'teki BigInteger sınıfı değişmez ve benim için kullanışlı olmayan bir deneyim. Boyutu 2 inç (yaklaşık 100MB) varsa, Ekle işlemi üçüncü bir 100 MB BigInt sonuçlanır. Örneğin, iki orijinalden birini değiştirirseniz daha hızlı yapılabilir.

C = A + B means allocating 100MB for C (this is what BigInt does) 
A = A + B means you no longer have the original A, but a much faster calculation 
+0

Teşekkürler. Önerdiğiniz önerileri de içeren üç kütüphaneyi indirdikten sonra, herhangi bir yerde bir Log fonksiyonu bulamadım. Bu kasıtlı ve uygulanması zor mu? –

+0

@RaheelKhan Bir kayan nokta günlüğüne veya en yüksek ayarlanmış bitin konumuna ihtiyacınız var mı? – harold

+0

Her ikisine de senaryoya bağlı olarak ihtiyacım var. En büyük bit kümesi BigInteger ile zaten önemsiz. Kayan nokta bana çok zaman harcıyor. –

1

kimse bulursa yararlı, burada yerleşik işlev kullanarak çok daha hızlı olduğunu BigInteger için bir Log Bankası 2 uygulamasıdır.

private static BigInteger LogBase2(BigInteger num) { 
    if (num <= Zero) 
     return MinusOne; //does not support negative values. 
    BigInteger i = Zero; 
    while (!(num >>= 1).IsZero) 
     i++; 
    return i; 
} 
+1

Teşekkürler. Çok eski bir soru ama hala geri dönmek ve mükemmel bir karşılaştırma yapmak istiyorum. –

İlgili konular