• Keine Ergebnisse gefunden

Aufgabe 4 Erweiterung um Just-in-Time-Compiler

N/A
N/A
Protected

Academic year: 2022

Aktie "Aufgabe 4 Erweiterung um Just-in-Time-Compiler"

Copied!
17
0
0

Wird geladen.... (Jetzt Volltext ansehen)

Volltext

(1)

Aufgabe 4 – Erweiterung um Just-in-Time-Compiler

Dr.-Ing. Volkmar Sieh

Department Informatik 4 Verteilte Systeme und Betriebssysteme Friedrich-Alexander-Universität Erlangen-Nürnberg

WS 2021/2022

V. Sieh Erweiterung um JIT (WS21/22) 1 – 17

(2)

Einführung

Entwickelt werden soll ein virtuelles (vereinfachtes) SPiC-Board mit ATmega32-Mikrokontroller mit JIT-Compiler.

V. Sieh Erweiterung um JIT (WS21/22) Programmieraufgaben 2 – 17

(3)

SPiC-Board – Aufbau (vereinfacht)

Aufgabe 4 (unverändert gegenüber Aufgabe 3):

V. Sieh Erweiterung um JIT (WS21/22) SPiC-Board – Aufbau 3 – 17

(4)

Geforderte Funktionalität

Der CPU-Teil des Mikrokontrollers soll jetzt als Just-in-Time-Compiler ausgeführt werden.

Basisblöcke sollen einmal am Stück compiliert und nachfolgend ggf.

mehrfach ausgeführt werden können.

Optimierungen (Block-Verkettungen, Lazy-Flags-Berechnungen u.ä.) sind nicht gefordert.

Bestehende Unterprogramme (z.B. zur Berechnung eine

Additions-Ergebnisses mit seinen Flags) dürfen vom JIT-Code aus verwendet werden.

V. Sieh Erweiterung um JIT (WS21/22) Geforderte Funktionalität 4 – 17

(5)

Geforderte Funktionalität

Getestet werden soll die neue CPU mit den bisherigen Testprogrammen. Diese sollen lauffähig bleiben.

V. Sieh Erweiterung um JIT (WS21/22) Geforderte Funktionalität 5 – 17

(6)

Bewertung

Die Performance des alten Interpreters und die des neuen JIT-Ansatzes soll verglichen werden.

Berechnen Sie den Speedup.

Identifizieren Sie die noch bestehenden Flaschenhälse.

V. Sieh Erweiterung um JIT (WS21/22) Geforderte Funktionalität 6 – 17

(7)

Hinweise

Im Folgenden:

(Gedankliche) Schritte, um von einem Interpreter zu einem Just-in-Time-Compiler zu kommen...

V. Sieh Erweiterung um JIT (WS21/22) Geforderte Funktionalität 7 – 17

(8)

Hinweise

void step(struct state *s) {

/* 1. Pipeline-Stufe: Instruktion holen */

inst = fetch(s->pc++);

switch (inst_format(inst) { case ALU_REG_REG:

/* 2. Pipeline-Stufe: Operanden holen */

op1 = reg_read(s, (inst >> 0) & 0xf);

op2 = reg_read(s, (inst >> 4) & 0xf);

/* 3. Pipeline-Stufe: Rechnen */

res = alu(s, (inst >> 24) & 0xf, op1, op2);

/* 4. Pipeline-Stufe: Ergebnis speichern */

reg_write(s, (inst >> 20) & 0xf, res);

break;

case ALU_REG_IMM:

/* 2. Pipeline-Stufe: Operanden holen */

op1 = reg_read(s, (inst >> 0) & 0xf);

op2 = (inst >> 4) & 0xffff;

/* 3. Pipeline-Stufe: Rechnen */

res = alu(s, (inst >> 24) & 0xf, op1, op2);

/* 4. Pipeline-Stufe: Ergebnis speichern */

reg_write(s, (inst >> 20) & 0xf, res);

break;

case ...

...

} }

Basisblock:

15: add %r0, %r1 16: sub $13, %r1 17: mov %r1, %r8 18: cmp $0, %8 19: jne 25

Wie sehe entsprechende C-Funktion aus?

V. Sieh Erweiterung um JIT (WS21/22) Geforderte Funktionalität 8 – 17

(9)

Hinweise

void step(struct state *s) {

/* 1. Pipeline-Stufe: Instruktion holen */

inst = fetch(s->pc++);

switch (inst_format(inst) { case ALU_REG_REG:

/* 2. Pipeline-Stufe: Operanden holen */

op1 = reg_read(s, (inst >> 0) & 0xf);

op2 = reg_read(s, (inst >> 4) & 0xf);

/* 3. Pipeline-Stufe: Rechnen */

res = alu(s, (inst >> 24) & 0xf, op1, op2);

/* 4. Pipeline-Stufe: Ergebnis speichern */

reg_write(s, (inst >> 20) & 0xf, res);

break;

case ALU_REG_IMM:

/* 2. Pipeline-Stufe: Operanden holen */

op1 = reg_read(s, (inst >> 0) & 0xf);

op2 = (inst >> 4) & 0xffff;

/* 3. Pipeline-Stufe: Rechnen */

res = alu(s, (inst >> 24) & 0xf, op1, op2);

/* 4. Pipeline-Stufe: Ergebnis speichern */

reg_write(s, (inst >> 20) & 0xf, res);

break;

case ...

...

} }

15: add %r0, %r1 16: sub $13, %r1 17: mov %r1, %r8 18: cmp $0, %r8 19: jne 25

void block(struct state *s) { op1 = reg_read(s, 0);

op2 = reg_read(s, 1);

res = alu(s, ADD, op1, op2);

reg_write(s, 1, res);

op1 = reg_read(s, 1);

op2 = 13;

res = alu(s, SUB, op1, op2);

reg_write(s, 1, res);

op1 = reg_read(s, 1);

res = op1;

reg_write(s, 8, res);

op1 = reg_read(s, 8);

op2 = 0;

alu(s, SUB, op1, op2);

if (! s->z) { s->pc = 25;

} else { s->pc = 20;

} }

V. Sieh Erweiterung um JIT (WS21/22) Geforderte Funktionalität 9 – 17

(10)

Hinweise

void block(struct state *s) { int op1;

int op2;

int res;

op1 = reg_read(s, 0);

op2 = reg_read(s, 1);

res = alu(s, ADD, op1, op2);

reg_write(s, 1, res);

op1 = reg_read(s, 1);

op2 = 13;

res = alu(s, SUB, op1, op2);

reg_write(s, 1, res);

op1 = reg_read(s, 1);

res = op1;

reg_write(s, 8, res);

op1 = reg_read(s, 8);

op2 = 0;

alu(s, SUB, op1, op2);

if (! s->z) { s->pc = 25;

} else { s->pc = 20;

} }

Wie sehe entsprechender Assembler-Code aus?

V. Sieh Erweiterung um JIT (WS21/22) Geforderte Funktionalität 10 – 17

(11)

Hinweise

void block(struct state *s) { int op1;

int op2;

int res;

op1 = reg_read(s, 0);

op2 = reg_read(s, 1);

res = alu(s, ADD, op1, op2);

reg_write(s, 1, res);

...

}

block: // s in %rdi pushq %rbp movq %rdi, %rbp subq $16, %rsp movq %rbp, %rdi movl $0, %esi call reg_read movl %eax, 0(%rsp) movq %rbp, %rdi movl $1, %esi call reg_read movl %eax, 4(%rsp) movq %rbp, %rdi movl $ADD, %esi movl 0(%rsp), %edx movq 4(%rsp), %ecx call alu movl %eax, 8(%rsp) movq %rbp, %rdi movl $1, %esi movl 8(%rsp), %edx call reg_write ...

addq $16, %rsp popq %rbp ret

V. Sieh Erweiterung um JIT (WS21/22) Geforderte Funktionalität 11 – 17

(12)

Hinweise

void block(struct state *s) { int op1;

int op2;

int res;

...

if (! s->z) { s->pc = 25;

} else { s->pc = 20;

} }

block: // s in %rdi pushq %rbp movq %rdi, %rbp subq $16, %rsp ...

cmpb $0, off_z(%rbp) jne l1

movl $25, off_pc(%rbp) jmp l2;

l1: movl $20, off_pc(%rbp) l2:

addq $16, %rsp popq %rbp ret

V. Sieh Erweiterung um JIT (WS21/22) Geforderte Funktionalität 12 – 17

(13)

Hinweise

block: // s in %rdi pushq %rbp movq %rdi, %rbp subq $16, %rsp movq %rbp, %rdi movl $0, %esi call reg_read movl %eax, 0(%rsp) ...

cmpb $0, off_z(%rbp) jne l1

movl $25, off_pc(%rbp) jmp l2;

l1: movl $20, off_pc(%rbp) l2:

addq $16, %rsp popq %rbp ret

Wie sehe Binär-Code aus?

V. Sieh Erweiterung um JIT (WS21/22) Geforderte Funktionalität 13 – 17

(14)

Hinweise

block: // s in %rdi pushq %rbp movq %rdi, %rbp subq $16, %rsp movq %rbp, %rdi movl $0, %esi call reg_read movl %eax, 0(%rsp) ...

cmpb $0, 0x5(%rbp) jne l1

movl $25, 0x12(%rbp) jmp l2;

l1: movl $20, 0x12(%rbp) l2:

addq $16, %rsp popq %rbp ret

55 push %rbp

48 89 fd mov %rdi,%rbp

48 83 ec 10 sub $0x10,%rsp

48 89 ef mov %rbp,%rdi

be 00 00 00 00 mov $0x0,%esi e8 (reg_read - lab1) callq reg_read

lab1: 89 04 24 mov %eax,(%rsp)

...

80 7d 05 00 cmpb $0x0,0x5(%rbp) 75 (lab3 - lab2) jne lab3

lab2: c7 45 12 19 00 00 00 movl $0x19,0x12(%rbp) eb (lab4 - lab3) jmp lab4

lab3: c7 45 12 14 00 00 00 movl $0x14,0x12(%rbp) lab4: 48 83 c4 10 add $0x10,%rsp

5d pop %rbp

c3 retq

V. Sieh Erweiterung um JIT (WS21/22) Geforderte Funktionalität 14 – 17

(15)

Hinweise

Damit Bytes im Speicher ausführbar sind, muss der entsprechende Speicherbereit in der MMU als „ausführbar” markiert sein.

In der MMU werden alle Speicherbereiche als Seiten verwaltet. Seiten müssen an Adressen liegen, die durch die Seitengröße teilbar sind.

Unter Linux/gcc:

#include <sys/mman.h>

char jit_buf[256*4096] __attribute__((aligned(4096)));

int ret;

ret = mprotect(jit_buf, sizeof(jit_buf), PROT_READ | PROT_WRITE | PROT_EXEC);

assert(0 <= ret);

V. Sieh Erweiterung um JIT (WS21/22) Geforderte Funktionalität 15 – 17

(16)

Hinweise

Hinweise x86_64-Programmierung:

https://de.wikipedia.org/wiki/AMD64

V. Sieh Erweiterung um JIT (WS21/22) Geforderte Funktionalität 16 – 17

(17)

Hinweise

Bei Problemen gerne/rechtzeitig melden!

V. Sieh Erweiterung um JIT (WS21/22) Geforderte Funktionalität 17 – 17

Referenzen

ÄHNLICHE DOKUMENTE

Das häufigste Problem, welches Unternehmen im Rahmen des Programms MMU lösen wollten, waren knappe Parkierungsflächen. Eine Verlagerung vom MIV auf den ÖV hätte dieses Problem

An adversary constructing a new exploit need only conform their memory disclosure to our interface and provide an initial code pointer in Step ¶ , then let our framework take over

Java Byte Code and CIL (Common Intermediate Language, cf. .NET) are examples for stack machine code, i.e., intermediate results are stored on a runtime stack.. Further

Bevor die Schülerinnen und Schüler selbst einen Kommentar verfassen, setzen sie sich mit Textbeispielen auseinander, um zum einen ein Gespür für die Besonderheiten in Bezug auf

Der Verstoß gegen Gesetze und Vorschriften zum Schutz der Gesundheit durch Autoindustrie und Zulassungsbehörden darf von Alexander Dobrindt, Horst Seehofer und den

IV Behandlung beschränkter Vollstreckungsanträge auf H erausgabe___ 110 D. Einleitung des Zwangsversteigerungsverfahrens als Druckmittel zur For­ derungseintreibung

Der Kanton Tessin arbeitet seit einigen Jahren erfolgreich und eng mit dem Programm Mobilitätsmanagement für Unternehmen von EnergieSchweiz zusammen und unterstützt Gemeinden

Längerfristig sollte eine Sammlung verschiedenster Bilder aus Zeitschriften, Reklame etc. angelegt wer- den, die sich rund um das Thema Sexualität, Körper, Liebe … bewegen. Dies