2014-06-23 17 views
14

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

= "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). –

+1

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. –

+0

@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. –

cevap

3

Bu sorunuza doğrudan bir cevap değil, ama hiç bakarak değer olabilir: apparently, hyperthreading can cause your cache to thrash. Soruna ne tür bir sorunun neden olduğunu görmek için valgeri kontrol etmeye çalıştın mı? Her iş parçacığının yığınının üstüne biraz önemsiz ayırmaktan kurtulmak için hızlı bir düzeltme olabilir, böylece iş parçacıklarınız birbirlerinin önbellek çizgilerini tekmelemeye son vermez.

It looks like your CPU is 4-way set associative Bu yüzden, 8 ileti dizisinde, gerçekten ne yazık ki hizalanmış erişimlerle sonuçlanabileceğini düşünmek saçma değildir. Matrisleriniz önbelleğinizin büyüklüğünün bir katına hizalıysa ve bölgelere çiftleri birbirinden farklı bir şekilde ayırma çiftleri olsaydı, üçüncü bir iş parçacığı tarafından yapılan tesadüfi okumalar, çakışmalara neden olmaya başlamak için yeterli olur.

Hızlı bir test için - giriş matrislerinizi önbellek boyutunuzun katları olmayan bir değere dönüştürdüğünüzde (yani artık bir sınırda olmadıkları için) ve sorunlarınız kaybolursa, o zaman sizin için iyi bir şans vardır. Çatışmalarla ilgileniyor. İhracat GOMP_CPU_AFFINITY yana

+0

Bir noktada valgrind kullanmalıyım (hiç kullanmadım). Ancak hiper iş parçacığının işleri daha da kötüleştirmesi, benim kodumda şaşırtıcı değil. Hyper-threading, optimize edilmemiş kodlar için kullanışlıdır. Ayrıca, MKM'de GEMM çalıştırdığımda, sistemimde dört iş parçacığı kullanıyor ve sekiz değil. Belirli hihgly optimize kod için hyper-threading aslında daha kötü sonuçlar verir. –

İlgili konular