Code Injizieren / Assembly Inlining in Java?

8

Ich weiß, dass Java eine sichere Sprache ist, aber wenn Matrixberechnungen benötigt werden, kann ich etwas schneller ausprobieren?

Ich lerne __asm ​​{} in C ++, Digital-Mars Compiler und FASM. Ich möchte dasselbe in Java machen. Wie kann ich Inline-Assembler-Codes in Funktionen einbauen? Ist das überhaupt möglich?

In etwa so (eine vektorisierte Schleife, um alle Elemente eines Arrays ohne Verzweigung auf einen Wert zu fixieren, indem AVX die CPU unterstützt):

%Vor%

Ich möchte keinen Code-Injektor verwenden. Ich möchte die x86-Anweisungen von Intel oder AT & amp; T ansehen.

    
huseyin tugrul buyukisik 24.07.2012, 13:37
quelle

6 Antworten

13

Es gibt eine Abstraktionsschicht zwischen Ihrem Java-Code und der zugrunde liegenden Hardware, die solche Dinge prinzipiell unmöglich macht; Sie können technisch nicht wissen, wie Ihr Code auf dem zugrunde liegenden Computer dargestellt wird, da derselbe Bytecode auf verschiedenen Prozessoren und unterschiedlichen Architekturen ausgeführt werden kann.

Was Sie offiziell können tun, ist die Java Native Interface (JNI) zum Aufruf von nativem Code aus Ihrem Java-Code. Der Anruf-Overhead ist beträchtlich, und das Teilen von Daten mit Java ist ziemlich teuer, daher sollte dies nur für Stücke von nativem Code in anständiger Größe verwendet werden.

Theoretisch sollte eine solche Erweiterung jedoch möglich sein. Man kann sich einen Java-Compiler vorstellen, der auf eine bestimmte Plattform abzielt und Assembly-Escapes erlaubt. Der Compiler müsste seinen ABI veröffentlichen, damit Sie die Aufrufkonventionen kennen. Mir ist das aber nicht bewusst. Aber es gibt mehrere Compiler verfügbar , die Java direkt in nativen Code kompilieren; es ist möglich, dass einer von ihnen so etwas unterstützt, ohne dass ich es weiß oder erweitert werden könnte.

Schließlich gibt es auf einer anderen Ebene auch Bytecode-Assembler für die JVM, wie Jasmin . Ein Bytecode-Assembler lässt Sie schreiben " Maschinencode ", der direkt auf die JVM abzielt, und manchmal können Sie besseren Code schreiben, als der javac -Compiler erzeugen kann. Es macht Spaß, auf jeden Fall zu spielen.

    
Ernest Friedman-Hill 24.07.2012, 13:42
quelle
5

Sie können in Ihrem Java-Code keine direkte Inline-Assemblierung durchführen. Im Gegensatz zu dem, was von einigen anderen Antworten behauptet wird, ist das bequeme Aufrufen von Assembly ohne Durchlaufen einer Zwischenschicht C (oder C ++) möglich.

Exemplarische Vorgehensweise

Betrachten Sie die folgende Java-Klasse:

%Vor%

Die Hauptidee besteht darin, ein Symbol mit der JNI-Namenskonvention zu deklarieren. In diesem Fall lautet der in Ihrem Assembly-Code zu verwendende Name Java_MyJNIClass_printVersion . Dieses Symbol muss von anderen Übersetzungseinheiten sichtbar sein, was beispielsweise mit der Direktive public in FASM oder der Direktive global in NASM erreicht werden kann.

Schreiben Sie Ihren Assemblercode mit den Aufrufkonventionen der Zielarchitektur (Argumente können in Registern, auf dem Stack, in anderen Speicherstrukturen usw. übergeben werden). Das erste an Ihre Assembly-Funktion übergebene Argument ist ein Zeiger auf JNIEnv , der selbst ein Zeiger auf die JNI-Funktionstabelle ist. Verwenden Sie es, um JNI-Funktionen aufzurufen. Zum Beispiel mit NASM und Targeting x86_64:

%Vor%

Indizes für JNI-Funktionen finden Sie in der Java-Dokumentation . Da die JNI-Funktionstabelle im Grunde ein Array von Zeigern ist, vergessen Sie nicht, diese Indizes mit der Größe eines Zeigers in der Zielarchitektur zu multiplizieren.

Das zweite an Ihre Assembly-Funktion übergebene Argument ist eine Referenz auf die aufrufende Java-Klasse oder das aufrufende Objekt. Alle nachfolgenden Argumente sind die Parameter Ihrer systemeigenen Java-Methode.

Schließlich assemblieren Sie Ihren Code, um eine Objektdatei zu generieren, und erstellen Sie dann eine gemeinsam genutzte Bibliothek aus dieser Objektdatei (GCC kann diesen letzten Schritt mit einem Befehl ähnlich wie gcc -shared -o ... ausführen).

Beispiel für die Ausführung

Ich habe ein vollständig lauffähiges Beispiel auf GitHub erstellt , schau dir das an und spiele damit herum, um besser zu werden Verständnis.

    
Pyves 11.05.2017 22:13
quelle
2

Es ist möglich, Assembly von Java mit der Java-Technologie auf maschineller Ebene aufzurufen. Es packt transparent Ihren Assembler-Code, der in Java geschrieben ist, aber sehr ähnlich der am häufigsten verwendeten Assembly-Syntax, in eine native Bibliothek. Und als nächstes müssen Sie nur eine native Methode aufrufen, die Sie in derselben Klasse definieren, in der Ihre Assembly geschrieben ist. Sie bleiben also immer in der Java-Umgebung und müssen nicht von der Java-IDE zu einigen Assemblierungswerkzeugen und dann zurück zu Java wechseln.

    
alexbav 31.12.2014 00:31
quelle
2

Sie können Assembly nicht direkt aus Java aufrufen. Aber Sie können C-Code über JNI aufrufen, und von dort aus können Sie die Baugruppe aufrufen.

Dieser Artikel zeigt, wie.

    
andrew cooke 24.07.2012 13:43
quelle
1

Sie verwenden JNI oder JNA und rufen Ihre nativen Funktionen von Java auf. Oder als Alternative haben Sie Bytecode als InputStream und machen eine Java-Klasse daraus.

    
belgther 24.07.2012 13:44
quelle
1

Sie können sich auch Aparapi ansehen.

    
Dmitry Leskov 26.07.2012 10:51
quelle

Tags und Links