2015-05-14 5 views
9

Ich habe ein Python-Programm entwickelt, das umfangreiche numerische Berechnungen durchführt. Ich laufe es auf einem Linux-Rechner mit 32 Xeon-CPUs, 64 GB RAM und Ubuntu 14.04 64-Bit. Ich starte mehrere Python-Instanzen mit verschiedenen Modellparametern parallel, um mehrere Prozesse zu nutzen, ohne mich um die globale Interpreter-Sperre (GIL) kümmern zu müssen. Wenn ich die CPU-Auslastung unter Verwendung von htop überwache, sehe ich, dass alle Kerne verwendet werden, jedoch meistens vom Kernel. Im Allgemeinen beträgt die Kernel-Zeit mehr als die doppelte Benutzerzeit. Ich befürchte, dass auf der Systemebene viel Aufwand entsteht, aber ich kann den Grund dafür nicht finden.Hohe Kernel-CPU beim Ausführen mehrerer Python-Programme

Wie würde man die hohe Kernel-CPU-Auslastung reduzieren?

Hier sind einige Beobachtungen, die ich gemacht:

  • Dieser Effekt tritt unabhängig davon, ob ich laufe 10 Jobs oder 50. Wenn es weniger Arbeitsplätze als Kerne sind nicht alle Kerne verwendet werden, aber diejenigen, die sind haben noch eine hohe CPU-Auslastung durch den Kernel
  • ich die innere Schleife numba mit implementiert, aber das Problem ist nicht im Zusammenhang mit diesem, da dem numba Teil Entfernen löst nicht das Problem
  • ich aber auch, dass es sein könnte, im Zusammenhang mit der Verwendung von python2 ähnlich der problem mentioned in this SO question bu t Wechsel von python2 zu python3 hat sich nicht sehr geändert
  • Ich habe die Gesamtzahl der vom OS durchgeführten Kontextwechsel gemessen, die ungefähr 10000 pro Sekunde betragen. Ich bin mir nicht sicher, ob dies eine große Anzahl
  • Ich habe versucht, ist die Python-Zeitscheiben zu erhöhen, indem sys.setcheckinterval(10000) (für python2) und sys.setswitchinterval(10) (für python3) Einstellung aber nichts davon half
  • Ich habe versucht, den Taskplaner zu beeinflussen, indem Sie schedtool -B PID aber das half auch nicht

Edit: Hier ist ein Screenshot von htop: enter image description here

ich liefauchund dies ist der Bericht von perf report -g graph:

Samples: 1M of event 'cycles', Event count (approx.): 1114297095227         
- 95.25%   python3 [kernel.kallsyms]       [k] _raw_spin_lock_irqsave ◆ 
    - _raw_spin_lock_irqsave                   ▒ 
     - 95.01% extract_buf                   ▒ 
      extract_entropy_user                  ▒ 
      urandom_read                    ▒ 
      vfs_read                     ▒ 
      sys_read                     ▒ 
      system_call_fastpath                  ▒ 
      __GI___libc_read                   ▒ 
- 2.06%   python3 [kernel.kallsyms]       [k] sha_transform   ▒ 
    - sha_transform                     ▒ 
     - 2.06% extract_buf                   ▒ 
      extract_entropy_user                  ▒ 
      urandom_read                    ▒ 
      vfs_read                     ▒ 
      sys_read                     ▒ 
      system_call_fastpath                  ▒ 
      __GI___libc_read                   ▒ 
- 0.74%   python3 [kernel.kallsyms]       [k] _mix_pool_bytes   ▒ 
    - _mix_pool_bytes                     ▒ 
     - 0.74% __mix_pool_bytes                  ▒ 
      extract_buf                    ▒ 
      extract_entropy_user                  ▒ 
      urandom_read                    ▒ 
      vfs_read                     ▒ 
      sys_read                     ▒ 
      system_call_fastpath                  ▒ 
      __GI___libc_read                   ▒ 
    0.44%   python3 [kernel.kallsyms]       [k] extract_buf    ▒ 
    0.15%   python3 python3.4         [.] 0x000000000004b055  ▒ 
    0.10%   python3 [kernel.kallsyms]       [k] memset     ▒ 
    0.09%   python3 [kernel.kallsyms]       [k] copy_user_generic_string ▒ 
    0.07%   python3 multiarray.cpython-34m-x86_64-linux-gnu.so [.] 0x00000000000b4134  ▒ 
    0.06%   python3 [kernel.kallsyms]       [k] _raw_spin_unlock_irqresto▒ 
    0.06%   python3 python3.4         [.] PyEval_EvalFrameEx  

Es scheint, als ob die meiste Zeit verbrachte _raw_spin_lock_irqsave ruft. Ich habe keine Ahnung, was das bedeutet.

+0

Haben Sie überprüft, was sonst noch auf dem System läuft? Die Ausgabe von "top" wäre interessant. – wallyk

+0

Ich habe nichts außergewöhnliches. Dies ist nicht einmal der Computer, den ich für meine tägliche Arbeit verwende. Ich habe der Frage einen Screenshot hinzugefügt. –

+0

Führen Sie 'perf record -a' von root (chdir zu'/tmp') und dann 'perf report' aus. Es gibt Ihnen eine Ahnung, was der Kernel macht. – myaut

Antwort

5

Wenn das Problem im Kernel besteht, sollten Sie ein Problem mit einem Profiler wie OProfile oder perf eingrenzen.

I.e. Führen Sie perf record -a -g aus und lesen Sie dann die in perf data gespeicherten Profilerstellungsdaten unter Verwendung von perf report. Siehe auch: linux perf: how to interpret and find hotspots.


In Ihrem Fall hohe CPU-Auslastung wird für /dev/urandom durch den Wettbewerb verursacht - es ist nur ein Thread von ihm lesen können, aber mehrere Python-Prozesse so tun.

Python-Modul random verwendet es nur für die Initialisierung. ICH.e:

$ strace python -c 'import random; 
while True: 
    random.random()' 
open("/dev/urandom", O_RDONLY)  = 4 
read(4, "\16\36\366\36}"..., 2500) = 2500 
close(4)         <--- /dev/urandom is closed 

Sie für /dev/urandom auch explizit durch Verwendung os.urandom oder SystemRandom Klasse fragen. Überprüfen Sie also Ihren Code, der sich mit Zufallszahlen beschäftigt.

+2

Vielen Dank für Ihre Hilfe! Nun, da ich wusste, wonach ich suchte, wurde mir klar, dass ich tatsächlich einen Bug in * meiner * Codebasis hatte, wo ich aus irgendeinem Grund den Zufallszahlengenerator jedes Mal initialisieren würde, wenn ein bestimmtes Basisobjekt erstellt wurde. Ich konnte diesen Teil nur in einem alten Code finden, weil ich genau wusste, wonach ich suchte! Ich werde deine Antwort so schnell wie möglich annehmen. –

Verwandte Themen