diff --git a/.obsidian/workspace.json b/.obsidian/workspace.json index 5a5fd60..986e4a4 100644 --- a/.obsidian/workspace.json +++ b/.obsidian/workspace.json @@ -4,11 +4,11 @@ "type": "split", "children": [ { - "id": "c0e94983c70f8454", + "id": "18b8b1518b5f7eab", "type": "tabs", "children": [ { - "id": "44290f906d2f39dd", + "id": "678ded2130f08e88", "type": "leaf", "state": { "type": "markdown", @@ -20,61 +20,8 @@ "icon": "lucide-file", "title": "Teoría_2425" } - }, - { - "id": "b9dc483ed444f858", - "type": "leaf", - "state": { - "type": "markdown", - "state": { - "file": "TERCERO/SPD/Teoría_2425.md", - "mode": "source", - "source": false - }, - "icon": "lucide-file", - "title": "Teoría_2425" - } - }, - { - "id": "9c276221889aa33a", - "type": "leaf", - "state": { - "type": "image", - "state": { - "file": "TERCERO/ATR1/images/Pasted image 20241127110759.png" - }, - "icon": "lucide-image", - "title": "Pasted image 20241127110759" - } - }, - { - "id": "fdf44efc147788ae", - "type": "leaf", - "state": { - "type": "image", - "state": { - "file": "TERCERO/ATR1/images/Pasted image 20241127111215.png" - }, - "icon": "lucide-image", - "title": "Pasted image 20241127111215" - } - }, - { - "id": "1ca3e3801d0cdb51", - "type": "leaf", - "state": { - "type": "markdown", - "state": { - "file": "TERCERO/ATR1/Teoría_2425.md", - "mode": "source", - "source": false - }, - "icon": "lucide-file", - "title": "Teoría_2425" - } } - ], - "currentTab": 4 + ] } ], "direction": "vertical" @@ -227,21 +174,22 @@ "obsidian-git:Open Git source control": false } }, - "active": "1ca3e3801d0cdb51", + "active": "678ded2130f08e88", "lastOpenFiles": [ - "TERCERO/IA/Teoría_2425.md", - "TERCERO/ATR1/images/Pasted image 20241204111952.png", - "TERCERO/ATR1/images/Pasted image 20241204111556.png", - "TERCERO/ATR1/images/Pasted image 20241204110546.png", - "TERCERO/ATR1/images/Pasted image 20241204105723.png", - "TERCERO/ATR1/images/Pasted image 20241204105459.png", - "TERCERO/ATR1/Teoría_2425.md", + "TERCERO/SPD/images/Imagen de WhatsApp 2024-12-09 a las 20.00.56_ae187147.jpg", + "TERCERO/SPD/images/Imagen de WhatsApp 2024-12-09 a las 19.58.16_359536b7.jpg", + "TERCERO/SPD/images/Imagen de WhatsApp 2024-12-09 a las 19.56.10_a7e685e5.jpg", + "TERCERO/SPD/images/Pasted image 20241209194450.png", "TERCERO/SPD/Teoría_2425.md", - "TERCERO/SPD/images/Pasted image 20241202205510.png", - "TERCERO/SPD/images/Pasted image 20241202214411.png", - "TERCERO/SPD/images/Pasted image 20241202214354.png", - "TERCERO/SPD/images/Pasted image 20241202214247.png", - "TERCERO/SPD/images/Pasted image 20241202214242.png", + "TERCERO/SPD/images/Pasted image 20241209194420.png", + "TERCERO/SPD/images/arriba.png", + "TERCERO/SPD/images/Pasted image 20241209181348.png", + "TERCERO/SPD/images/Pasted image 20241209180114.png", + "TERCERO/SPD/images/Pasted image 20241209175932.png", + "TERCERO/SPD/images/abajo.png", + "TERCERO/ATR1/images/Pasted image 20241127110759.png", + "TERCERO/ATR1/Teoría_2425.md", + "TERCERO/IA/Teoría_2425.md", "TERCERO/SS/SS 24-25.md", "TERCERO/SS/SS Lab.md", "conflict-files-obsidian-git.md", diff --git a/TERCERO/SPD/Teoría_2425.md b/TERCERO/SPD/Teoría_2425.md index 2b6761a..0702168 100644 --- a/TERCERO/SPD/Teoría_2425.md +++ b/TERCERO/SPD/Teoría_2425.md @@ -145,7 +145,129 @@ graph TD; 7[Linkado y .exe nativo] --> 10[CPU] 9[Ensamblador nativo] --> 10[CPU] ``` -# TEMA 3: Instruction Level Parallelism (ILP) +# TEMA 2: ILP basado en planificación estática +## 1. Introducción +Se realiza la **planificación** (o **scheduling**) para reordenar las instrucciones con el objetivo de evitar los bloqueos de datos. Teniendo en cuenta el concepto de dependencia, se puede modelar un programa como un grafo de dependencias reales (RAW), pero existe un **límite de CPI (data-flow-limit)**: +- Sólo se ven las fases de ALU y EX/ME. +- Las otras (ID, ID, WB) se realizan en paralelo. +![[Pasted image 20241209181348.png]] +## 2. Desenrollado de bucles +Los bucles suelen ocupar más del 90% del $t_{CPU}$. +```c +double s, x[M], y[M]; int i; +for(i = 0; i < M; i++) +{ + y[i] = x[i] * s; +} +``` +Si el bucle es paralelizable (iteraciones independientes) se puede "desenrollar": +```c +for(i = 0; i < M % 3; i++) // módulo para las iteraciones bajas (pequeñas) +{ + y[i] = x[i] * s; +} + +for( ; i < M; i++) +{ + y[i] = x[i] * s; + y[i + 1] = x[i + 1] * s; + y[i + 2] = x[i + 2] * s; +} +``` +En bajo nivel (el segundo bucle) quedaría algo como: +```riscv +bucle: LD F2, 0(R1) + MULTD F4, F2, F24 ; F24 contiene el valor de s + SD (R3)0, F4 ; se guarda en y[i] + LD F2, 8(R1) + MULTD F4, F2, F24 + SD (R3)8, F4 ; se guarda en y[i + 1] + LD F2, 16(R1) + MULTD F4, F2, F24 ; se guarda en y[i + 2] + SD (R3)16, F4 +;------------------------------------------------------ + ADDI R1, R1, 8*3 + ADDI R3, R3, 8*3 + SLTI R7, R1, fin_array_x + BNEZ R7, bucle +``` +Donde por encima de la línea están las **instrucciones útiles** y por debajo las de **overhead**. En el bucle usamos renombrado de registros para evitar las dependencias **WAW** y **WAR**. Usamos la notacion prima ( $'$ ) por simplicidad: +```riscv +bucle: LD F2, 0(R1) + MULTD F4, F2, F24 ; F24 contiene el valor de s + SD (R3)0, F4 ; se guarda en y[i] + + LD F2', 8(R1) + MULTD F4', F2', F24 + SD (R3)8, F4' ; se guarda en y[i + 1] + + LD F2'', 16(R1) + MULTD F4'', F2'', F24 ; se guarda en y[i + 2] + SD (R3)16, F4'' +;------------------------------------------------------ + ADDI R1, R1, 8*3 + ADDI R3, R3, 8*3 + SLTI R7, R1, fin_array_x + BNEZ R7, bucle +``` +Por último se entrelazan las instrucciones de las distintas iteraciones +```riscv +bucle: LD F2, 0(R1) + LD F2', 8(R1) + LD F2'', 16(R1) + + MULTD F4, F2, F24 ; F24 contiene el valor de s + MULTD F4', F2', F24 + MULTD F4'', F2'', F24 ; se guarda en y[i + 2] + + SD (R3)0, F4 ; se guarda en y[i] + SD (R3)8, F4' ; se guarda en y[i + 1] + SD (R3)16, F4'' +;------------------------------------------------------ + ADDI R1, R1, 8*3 + ADDI R3, R3, 8*3 + SLTI R7, R1, fin_array_x + BNEZ R7, bucle +``` +
Al reducir el nº de instrucciones, el CPI no es buena medida de rendimiento. Lo que sí se puede usar es el ciclos por elemento del vector procesado


Si se usa el desenrollado, quedarían varias instrucciones por iteración.