Beschleunigen Sie Python mit numba grob

Eine Bibliothek namens numba macht es relativ einfach, Python-Code zu beschleunigen. Hoffentlich können Sie es beschleunigen, indem Sie einfach "from numba import jit" und "@ jit" in die Zeile vor der Funktion schreiben, die Sie beschleunigen möchten.

Der Mechanismus scheint zu sein, dass numba den Code der virtuellen Python-Maschine erhält, ihn in LLVM IR kompiliert und LLVM verwendet, um ihn zu nativem Code zu machen. Bei der ersten Ausführung wird der Kompilierungsprozess ausgeführt, sodass er etwas langsamer ist. Wenn es sich jedoch um einen schweren Prozess handelt, kann numba auch unter Berücksichtigung der Kompilierungszeit schneller sein.

Vorteile und Nachteile

Ich werde es zuerst erwähnen.

Vorteil

――In einigen Fällen können Sie problemlos beschleunigen, ohne den Code selbst zu ändern. ――Selbst eine Codeänderung vorliegt, handelt es sich häufig um eine geringfügige Änderung.

Nachteil

Beispiel

Hier sind einige Beispiele, die sehr gut funktionieren. Ich weiß es nicht, aber es gibt einige sehr langsame Funktionen.

import sys
sys.setrecursionlimit(100000)

def ack(m, n):
    if m == 0:
        return n + 1
    if n == 0:
        return ack(m - 1, 1)
    return ack(m - 1, ack(m, n - 1))

Ich werde die Zeit für einen Moment messen.

import time
from contextlib import contextmanager

@contextmanager
def timer():
    t = time.perf_counter()
    yield None
    print('Elapsed:', time.perf_counter() - t)

with timer():
    print(ack(3, 10))

8189 Elapsed: 10.270420542001375

Es dauerte 10 Sekunden.

Das Erhöhen der Anzahl wird länger dauern, aber ich empfehle es nicht, weil es wirklich Zeit braucht. Insbesondere wenn Sie 3 auf 4 erhöhen, werden Sie wahrscheinlich nicht fertig sein, bis Sie sterben, also empfehle ich es überhaupt nicht. Diese Funktion ist [Ackerman-Funktion](https://ja.wikipedia.org/wiki/%E3%82%A2%E3%83%83%E3%82%AB%E3%83%BC%E3%83%9E Es ist bekannt als% E3% 83% B3% E9% 96% A2% E6% 95% B0).

Lassen Sie uns dies mit numba beschleunigen.

from numba import jit

@jit
def ack(m, n):
    if m == 0:
        return n + 1
    if n == 0:
        return ack(m - 1, 1)
    return ack(m - 1, ack(m, n - 1))

#Erstes Mal
with timer():
    print(ack(3, 10))

#Zweites Mal
with timer():
    print(ack(3, 10))

#Drittes Mal
with timer():
    print(ack(3, 10))

8189 Elapsed: 0.7036043469997821 8189 Elapsed: 0.4371343919992796 8189 Elapsed: 0.4372558859977289

Was 10 Sekunden dauerte, ist zum ersten Mal auf 0,7 Sekunden und zum zweiten und nachfolgenden Mal auf 0,4 Sekunden geschrumpft. Wenn dies nur durch Hinzufügen einer Zeile geschieht, ist dies wirklich ein gutes Geschäft.

Wenn es nicht schneller ist als du denkst

Der Objektmodus kann verwendet werden.

numba hat den No Python-Modus und den Object-Modus. Wenn es einmal im No Python-Modus kompiliert wurde und fehlschlägt, wird es im Object-Modus kompiliert. (Diese Spezifikation wird jedoch in Zukunft verschwinden. Es scheint, dass standardmäßig nur kein Python-Modus verfügbar ist. Der Objektmodus ist optional.)

Ersteres behandelt alle Typen direkt, während letzteres Python-Objekte über die Python C-API trifft und ersteres schneller ist. Darüber hinaus kann Letzteres die Schleife möglicherweise nicht effizient in nativen Code umschreiben, während Ersteres die Schleife effizienter macht. (Loop-Jitting)

Um den No Python-Modus zu erzwingen, schreiben Sie "@jit (nopython = True)" oder "@ njit". Dies führt jedoch häufig zu Fehlern wie "Ich kenne den Typ nicht".

Grundsätzlich,

Sie können den Typ mit einer solchen Methode klären.

Relativ einfach zu unterstützen Kein Python-Modus

--Schneiden Sie nur den schweren Berechnungsteil für eine andere Funktion aus und lassen Sie ihn numba entsprechen ――Selbst wenn Sie das Teil ausschneiden, das den Typ durcheinander bringt oder es dem Objekt zuweist, sollten Sie darüber nachdenken, es zu löschen. --numba Überlegen Sie, wie Sie dies mit numba in Form einer Vor- oder Nachbearbeitung des entsprechenden Teils vermeiden können

Usw. werden empfohlen. Seien Sie sich bewusst, dass das, was Python kann, mit Python gemacht wird und was Python nicht kann, mit numba.

Versuchen Sie zu parallelisieren

Mit "@ jit (parallel = True)" können Sie "prange" anstelle von "range" in der for-Schleife verwenden (erfordert "from numba import prange").

Mit prange geschriebene Schleifen werden parallelisiert.

Kompilierter Ergebniscache

Mit @ jit (cache = True) können Sie das Kompilierungsergebnis in eine Cache-Datei schreiben und die Probleme beim Kompilieren jedes Mal vermeiden.

Verwenden Sie fastmath

Es kann mit @jit (fastmath = True) verwendet werden. Aktivieren Sie Fastmath, das auch in gcc und clang enthalten ist. Es ist eine etwas gefährliche Optimierung, die Float-Berechnungen beschleunigt.

Verwenden Sie CUDA

Es ist nicht sehr einfach, aber Sie können CUDA vorerst verwenden. Wenn Sie CUDA bereits verwendet haben, erfahren Sie dies anhand des folgenden Codes.

Persönlich dachte ich, dass Cupy in Ordnung wäre, wenn dies der Fall wäre.

import numpy as np
from numba import cuda

@cuda.jit
def add(a, b, n):
    idx = cuda.threadIdx.x + cuda.blockIdx.x * cuda.blockDim.x
    if idx < n:
        a[idx] += b[idx]

N = 1000000
a_host = np.array(np.ones(N))
b_host = np.array(np.ones(N))
a_dev = cuda.to_device(a_host)
b_dev = cuda.to_device(b_host)

n_thread = 64
n_block = N // n_thread + 1

add[n_block, n_thread](a_dev,b_dev,N)

a_dev.copy_to_host(a_host)

print(a_host) # Expect: [2, 2, ..., 2]

Wenn Sie wütend werden, dass Sie nicht "libNVVM" haben, haben Sie entweder CUDA nicht installiert (Sie können es mit "conda install cudatoolkit" usw. installieren) oder Sie müssen Umgebungsvariablen festlegen.

Beispiel in Google Colab usw .:

import os
os.environ['NUMBAPRO_LIBDEVICE'] = "/usr/local/cuda-10.0/nvvm/libdevice"
os.environ['NUMBAPRO_NVVM'] = "/usr/local/cuda-10.0/nvvm/lib64/libnvvm.so"

Zusammenfassung

Sie können numba verwenden, um Ihren Python-Code grob zu beschleunigen. Ich habe gesehen, wie man es leicht benutzt.

Ich bin froh, wenn Sie es als Referenz verwenden können.

Verweise

Das offizielle Dokument ist nicht sehr lang und sehr hilfreich, wenn Sie nur dort lesen, wo Sie es benötigen. Leistungstipps ist besonders nützlich.

Für Umgebungsvariableneinstellungen bei Verwendung von CUDA https://colab.research.google.com/github/cbernet/maldives/blob/master/numba/numba_cuda.ipynb Ich bezog mich auf.

Recommended Posts

Beschleunigen Sie Python mit numba grob
Numba als Python zu beschleunigen
Messen Sie die WLAN-Geschwindigkeit mit Python
Hinweise zur Beschleunigung des Python-Codes mit Numba
So beschleunigen Sie Python-Berechnungen
Beschleunigen Sie die C / C ++ - Kompilierung mit ccache
Schreiben Sie Python nicht, wenn Sie es mit Python beschleunigen möchten
[Python] Runden Sie nur mit dem Operator ab
Ich habe Numba mit Python3.5 installiert und verwendet
FizzBuzz in Python3
Scraping mit Python
Scraping mit Python
Python mit Go
Twilio mit Python
In Python integrieren
Spielen Sie mit 2016-Python
AES256 mit Python
Getestet mit Python
Python beginnt mit ()
mit Syntax (Python)
Bingo mit Python
Zundokokiyoshi mit Python
Excel mit Python
Mikrocomputer mit Python
Mit Python besetzen
Explosive Geschwindigkeit mit Python (Flasche)! Web-API-Entwicklung
[Python] Geben Sie Ihr Bestes, um SQL Alchemy zu beschleunigen
Ich habe versucht, Python-Code zu beschleunigen, einschließlich der if-Anweisung mit Numba und Cython
Serielle Kommunikation mit Python
Zip, entpacken mit Python
Django 1.11 wurde mit Python3.6 gestartet
Python mit Eclipse + PyDev.
Socket-Kommunikation mit Python
Datenanalyse mit Python 2
Scraping in Python (Vorbereitung)
Versuchen Sie es mit Python.
Python lernen mit ChemTHEATER 03
Sequentielle Suche mit Python
"Objektorientiert" mit Python gelernt
Umgang mit Yaml mit Python
Löse AtCoder 167 mit Python
Serielle Kommunikation mit Python
[Python] Verwenden Sie JSON mit Python
Python lernen mit ChemTHEATER 05-1
Lerne Python mit ChemTHEATER
Führen Sie prepDE.py mit python3 aus
Python ~ Grammatikgeschwindigkeit lernen ~
1.1 Erste Schritte mit Python
Tweets mit Python sammeln
Binarisierung mit OpenCV / Python
3. 3. KI-Programmierung mit Python
Kernel-Methode mit Python
Geschwindigkeit der Listeneinschlussnotation in Python
Scraping mit Python + PhantomJS
Fahren Sie WebDriver mit Python
[Python] Mit CGIHTTPServer umleiten
Sprachanalyse mit Python
Denken Sie an Yaml mit Python
Kinesis mit Python betreiben