2013-01-15 21 views
52

Quartz Events ile ilgili bir performans sorunu yaşadık, daha spesifik olarak CGEventPost: ağır GPU yükü sırasında CGEventPost bloke edebilir. a small benchmark application to demonstrate the issue'u oluşturduk. Bu uygulama, olayları oluşturan, yayınlayan ve yayınlayan bir döngüdür.GPU yükü altında CGEventPost'un zayıf performansı

Uygulamanın çalıştırılmasının sonuçlarını aşağıda görebilirsiniz. İlk çalışma boşta bir sistemde. İkinci çalışma, kadranların olabildiğince yukarıya kranklanmasıyla FurMark (GPU stres testi) ile yapılır.

  • İçsel döngü ne kadar sürerse, temel olarak bir olayı yalnızca Quartz Olayları ile oluşturma, gönderme ve serbest bırakma işlemidir.
  • Dış programımız ne kadar süreyle uyandırılmayı bekliyor (uyku). Uyuduğumuz zamana yakın olmalı, ancak sistem basınç altındaysa gecikebilir.
  • Etkinlik, etkinlik kaydının ne kadar sürdüğünü gösterir.  

    18:58:01.683 EventPerformance[4946:707] Measurements: (outer should be close to 10) 
    18:58:01.684 EventPerformance[4946:707] inner (ms): 0.04, outer (ms): 11.02, CGEventPost (ms): 0.03 
    18:58:01.684 EventPerformance[4946:707] inner (ms): 0.04, outer (ms): 11.02, CGEventPost (ms): 0.03 
    18:58:01.685 EventPerformance[4946:707] inner (ms): 0.07, outer (ms): 10.26, CGEventPost (ms): 0.03 
    18:58:01.685 EventPerformance[4946:707] inner (ms): 0.06, outer (ms): 10.85, CGEventPost (ms): 0.05 
    18:58:01.686 EventPerformance[4946:707] inner (ms): 0.07, outer (ms): 10.41, CGEventPost (ms): 0.04 
    18:58:01.686 EventPerformance[4946:707] inner (ms): 0.04, outer (ms): 10.39, CGEventPost (ms): 0.03 
    18:58:01.686 EventPerformance[4946:707] inner (ms): 0.05, outer (ms): 11.02, CGEventPost (ms): 0.03 
    18:58:01.687 EventPerformance[4946:707] inner (ms): 0.03, outer (ms): 10.67, CGEventPost (ms): 0.03 
    18:58:01.687 EventPerformance[4946:707] inner (ms): 0.08, outer (ms): 10.09, CGEventPost (ms): 0.05 
    18:58:01.688 EventPerformance[4946:707] Averages: (outer should be close to 10) 
    18:58:01.688 EventPerformance[4946:707] avg inner (ms): 0.05, avg outer (ms): 10.64, avg post (ms): 0.03 
    

Burada olay gönderme ortalama olarak yaklaşık 0.03 ms sürdüğünü görebiliriz. Ayrıca iplik çok geç 0,5 ms kadar uyandırılmış gibi görünüyor. CGEventPost'ta ani bir artış yok. Sistem ağır GPU yük altında olduğunda

19:02:02.150 EventPerformance[5241:707] Measurements: (outer should be close to 10) 
19:02:02.151 EventPerformance[5241:707] inner (ms): 0.03, outer (ms): 10.23, CGEventPost (ms): 0.02 
19:02:02.151 EventPerformance[5241:707] inner (ms): 0.02, outer (ms): 10.54, CGEventPost (ms): 0.02 
19:02:02.151 EventPerformance[5241:707] inner (ms): 0.02, outer (ms): 11.01, CGEventPost (ms): 0.01 
19:02:02.152 EventPerformance[5241:707] inner (ms): 0.02, outer (ms): 10.74, CGEventPost (ms): 0.01 
19:02:02.152 EventPerformance[5241:707] inner (ms): 0.02, outer (ms): 10.20, CGEventPost (ms): 0.01 
19:02:02.152 EventPerformance[5241:707] inner (ms): 10.35, outer (ms): 11.01, CGEventPost (ms): 10.35 
19:02:02.152 EventPerformance[5241:707] inner (ms): 0.03, outer (ms): 10.02, CGEventPost (ms): 0.02 
19:02:02.153 EventPerformance[5241:707] inner (ms): 58.90, outer (ms): 10.11, CGEventPost (ms): 58.90 
19:02:02.153 EventPerformance[5241:707] inner (ms): 0.03, outer (ms): 10.12, CGEventPost (ms): 0.02 
19:02:02.153 EventPerformance[5241:707] Averages: (outer should be close to 10) 
19:02:02.371 EventPerformance[5241:707] avg inner (ms): 7.71, avg outer (ms): 10.44, avg post (ms): 7.71 

, bir olayı gönderme yerine mikrosaniye (artışlar) milisaniye alabilir. Aşırı GPU stresi altında (< 1 FPS), bu değer saniye alabilir. CGEventPost bazen GPU'nun geri dönmeden önce bazı işleri bitirmesini bekliyor gibi görünüyor. Bizim iplik hala fark edilebilir gecikme/sivri (dış) ile normal olarak planlanmaktadır.

Herhangi bir fikir takdir edilmektedir.

+2

Çok sayıda OpenCL çalışması gönderirken pencerelerde daha kötü efektler görüyorum (osx üzerinde olduğunuzu biliyorum): tüm GPU çizimi bir taramayı yavaşlatır. GPU'ların öncelik kavramı ya da bir wavefront'ın kaç yaşında olduğu gibi. – doug65536

+2

Yavaşlamanın nerede meydana geldiğini görmek için Cihazlar ile profil oluşturmayı deneyin. – monoxygen

+1

Bunu çalıştırdığınız bilgisayarda ne tür bir grafik kartı var? Entegre, entegre + ayrık veya ayrık? Farklı grafik kartı yapılandırmasına sahip bir sistem üzerinde farklı davranışlar alıp almayacağınızı görmek ilginç olacaktır. – monoxygen

cevap

5

Sana

Bu Instruments içinde "zamanlama" ya da "sistem çağrısı" cihazı kullanılarak teyit edebilir ... kuyruğu (mach portu altında yatan) dolduruyor ediyoruz sanırım. (Yeni bir boş belge oluşturun, aracı ekleyin, sonra File > Record Options...'un altında "ertelenmiş mod" öğesinin işaretlendiğinden emin olun.) Bu, uygulamanızda tüm iş parçacığı etkinliğini gösterecektir (iş parçacığı blokları, ne zaman uykuya girdiklerinde, etkinleştirildiklerinde ve neden) .

İlk olarak, CGEventPost numaralı iş parçacığının iş parçacığı önceliğini (cf. man 3 PTHREAD_SCHEDPARAM) yükseltmeyi denerim. Eğer iş parçacığınız daha düşük öncelikli bir iş parçacığında engellenirse, çekirdek önceliği engellemek ve görevinizin daha önce tamamlanmasını sağlamak için engelleme iş parçacığının önceliğini geçici olarak yükseltmelidir.

Genel aşağıdaki gibi bir 2 iplikli çözümü uygulamak zorunda olacağını düşünüyorum:

göndermek istediğiniz olaylar için bir kuyruk oluşturun. Olayları ana iş parçanızdan (veya olay gönderme iş parçacığından) bu sıraya gönderin, daha sonra kuyruğa çıkmak ve bekleyen olayları CGEventPost ile göndermek için ikinci bir iş parçacığı (oluşturduğunuz bir olay iş parçacığı iş parçacığı) iletin.

CGEventPost bloklarını bloke ettiğinizde, ikinci olay gönderme iş parçacığınız engellenir, ancak bu başka bir iş parçacığını engellemez. CGEventPost sonuçta engellemeyi kaldırdığında, etkinlik tüketici iş parçacığınız tarafından yayınlanan tüm olağan dışı etkinlikleri tüketir ve etkinlik tüketici iş parçacığı etkinlik gönderme işlemine devam edebilir.

Başka bir olasılık: olayları hatırlatabilir misiniz? Daha az etkinliğe katılabileceğiniz belirli tür olaylar (fare hareketleri?) Vardır. Muhtemelen hala CGEventPost kuyruk limitine gireceksiniz, bence 2 iplikli yaklaşım muhtemelen en iyi bahistir.

+0

Soruyu sorduğumdan beri, CGEventPost'dan GPU yükü altında çok daha iyi performans gösteren IOHIDPostEvent'e geçtik, ancak yine de başka durumlarda engelleniyor. – Dae

+0

Cihazları kullanarak, hem IOHID hem de Quartz için mach_msg_trap dosyasında bloke ettiğimizi ve muhtemelen bir mesaj almayı beklediğimizi gördük. Daha fazla ayrıntı elde etmeyi başaramadık (yani diğer tarafta kim ve neden engelliyor). – Dae

+0

Gerçek zamanlı önceliğe gelince, test uygulamasından yanlışlıkla kaldırıldı, ancak bizim gerçek projemizde var. (Ancak fark etmez). Birleştirme ve iş parçacığı uyguladık - öneri için teşekkürler! – Dae