Büyük yoğun matris çarpma kodu geliştiriyorum. Kodu görüntülediğimde, bazen dört çekirdek sistemimin tepe noktalarının yaklaşık% 75'ini alır ve diğer zamanlarda yaklaşık% 36 olur. Verimlilik, kodun yürütmeleri arasında değişmez. Ya% 75 ile başlar ve bu verimlilikle devam eder veya% 36 da başlar ve bu verimlilik ile devam eder.OpenMP ile hiper iş parçacığı nedeniyle yetersiz performans: iş parçacıklarının çekirdeklere nasıl bağlanacağı
Sorunu hiper-iş parçacığına ve iş parçacığı sayısını varsayılan sekiz yerine dört olarak ayarladığım gerçeğine kadar izledim. BIOS'ta hiper iş parçacığı devre dışı bıraktığımda sürekli olarak yaklaşık% 75 verimlilik elde ediyorum (ya da en azından hiç bir zaman ciddi düşüşü% 36'ya kadar göremiyorum).
herhangi paralel kod aramadan önce ben omp_set_num_threads(4)
yapmak. Kodumu çalıştırmadan önce export OMP_NUM_THREADS=4
'u denedim ancak eşdeğer gibi görünüyor.
BIOS'ta hiper iş parçacığı devre dışı bırakmak istemiyorum. Dört parçayı dört çekirdeğe bağlaman gerektiğini düşünüyorum. GOMP_CPU_AFFINITY
'un bazı farklı durumlarını test ettim ancak şu ana kadar verim hala% 36'dır. Hiper iş parçacığı ve çekirdeklerle eşleştirme nedir? E.g. iş parçacığı 0 ve iş parçacığı 1 aynı çekirdek ve iş parçacığı 2 ve iş parçacığı 3 başka bir çekirdeğe karşılık gelir mi?
nasıl BIOS içinde hiper iş parçacığı devre dışı bırakmak zorunda kalmamak için ben iplik göç etmeden her çekirdeğe konuları bağlayabilir? Belki sched_setaffinity kullanmam gerekiyor mu? benim şimdiki sistemin
bazı ayrıntılar: Linux çekirdeği 3.13, GCC 4.8 Intel Xeon E5-1620 (dört fiziksel çekirdek, sekiz hiper iş parçacığı).
Düzenleme: These options: Bu aynı zamanda görünüyor iyi
export OMP_PROC_BIND=true
Düzenleme çalışmak: Bu
export GOMP_CPU_AFFINITY="0 1 2 3 4 5 6 7"
veya
export GOMP_CPU_AFFINITY="0-7"
Düzenleme şimdiye kadar iyi çalışıyor gibi görünüyor de iyi iş (gemm adıdır) Benim yürütülebilir
numactl -C 0,1,2,3 ./gemm
ve
taskset -c 0,1,2,3 ./gemm
= "0 1 2 3 4 5 6 7" Bu konu elektron gibi atanır yani ... iplik 0 ve 4 çekirdekli 0, iplik 1 ve 5, Core 2 olduğu anlamına geliyor iyi sonuçlar verir orbitallerde. İlk önce her bir göbeği (diş 0-3) doldurur ve tüm göbekler bir dişe sahip olduğunda geriye gider ve aynı göbeğe ipler kalır (iplikler 4-7). –
Her ikisi de hwloc kitaplığından hwloc-ls veya Intel MPI'den gelen "cpuinfo", makine hakkında temel topoloji bilgilerini sağlar, örn. Mantıksal CPU numaralarının fiziksel çekirdeklere/konulara eşlenmesi. Numaralandırma, BIOS'a bağlıdır, fakat deneyimlerimde çoğu vaka, hiper-adımların bir "dış döngüde" çevrilmiş olmasıydı. Ayrıca, "0-7" kısa notlarını da kullanabilirsiniz. –
@HristoIliev, taşınabilirlik için, bunu yapmanın doğru yolu OMP_PLACES, örn. 'ihracat OMP_PLACES = çekirdek Open OpenMP4.0’dan. AMD sistemlerde her modül sadece bir FPU var ama iki konuları alır ve bunu doğrusal olarak atandığı https://stackoverflow.com/questions/19780554/what-limits-scaling-in-this-simple-openmp-program/19871592#19871592 düşünüyorum GOMP_CPU_AFFINITY = "0-7" yapmanın işe yaramayacağını düşünüyorum. Aslında OMP_PROC_BIND = true da iyi olabilir. Belki de en iyi çözüm budur. –