(i5 aile) SemaphoreSlim kıyasla benim kod performans farkı iseC# SpinWait Bu kod sıfır CPU yakın tüketir
public void SpinWait() {
for (int i = 0; i < 10000; i++)
{
Task.Factory.StartNew(() =>
{
var sw = new SpinWait();
while (true)
{
sw.SpinOnce();
}
});
}
}
(zaman iplik gerçekten haklı 5 vaka için 3x kere veya daha fazla olduğu Mops). Ancak, uzun süreli bekleme için kullanmaktan endişe duyuyorum. Standart tavsiye iki fazlı bekleme işlemini uygulamaktır. NextSpinWillYield
özelliğini kontrol edebilir ve varsayılan eğirme yinelemelerini vermeksizin bir sayaç + sıfırlama yapabilir ve bir semafor için geri dönüş yapabilirim.
Ancak uzun vadede beklemek için sadece SpinWait.SpinOnce
kullanmanın olumsuzlukları nelerdir? implementation'u inceledim ve gerektiğinde uygun şekilde verdim. Modern CPU'larda PAUSE komutunu kullanan ve Intel'a göre oldukça verimli olan Thread.SpinWait
kullanır.
Görev Yöneticisi'nin izlenmesinde bulduğum bir sorun, varsayılan ThreadPool algoritması nedeniyle kademeli olarak artması durumunda iş parçacıklarının sayısıdır (tüm görevler meşgul olduğunda her saniye bir iş parçacığı ekler). Bu, ThreadPool.SetMaxThreads
kullanılarak çözülebilir ve daha sonra iş parçacığı sayısı sabittir ve CPU kullanımı hala sıfıra yakındır.
Uzun süre bekletilen görevlerin sayısı sınırlanırsa, uzun süre beklemek için SpinWait.SpinOnce
'u kullanmanın diğer tuzakları nelerdir? CPU ailesi, işletim sistemi, .NET sürümüne bağlı mı?
(Sadece netleştirmek için: Hala Sadece nedenini SpinOnce her zaman kullanmıyor curios değilim, iki fazlı bekleyen uygulayacak)
Teşekkürler! BTW, kaç saniye mikrosaniyenin iplik uyandırmasını alır, örn. Eğer semaphore.WaitAsync (-1, jeton) 'da beklersam? Eğer spinwait ve 'SpinOne' verimleri' Sleep (1) 'ile yapılırsa, en kötü durumda' Sleep (1) 'dedikten sonra tam olarak bir sinyalin gelmesi durumunda en az 15 msn gecikmeyle karşılaşıyorum. Bunun yerine bir semaforya geçersem, semaphore.Release() 'den sonra uyanan bir iş parçacığının en kötü gecikmesi nedir? –
Makine üzerinde neler olup bittiğine bağlı. Ayrıca diğer süreçlerin ve tabii ki çekirdek konuların sahip olduğu iş parçacıkları ile rekabet etmek zorundasınız. Milisaniye değil, mikrosaniye alır. Sadece Kronometre ile ölçün, ara sıra en kötü durum oldukça uzun olabileceğinden, birçok ölçümün medyanını aldığınızdan emin olun. Ve bunun hakkında yapabileceğiniz bir şey olmadığını aklınızdan çıkarmayın, bu yüzden sadece bilgilendirme amaçlıdır. Asla Sleep() kullanmayın. –
Semaforun serbest bırakılmasının ardından .NET ile hiçbir ilgisi yok ve C/C++ veya hatta montaj bile işe yaramayacak mı? (sadece bu donanım/işletim sistemi tasarımı olduğunu anlamak için kullanmayın) –