cambios SS 2024-10-31 13:15:21
This commit is contained in:
14
.obsidian/workspace.json
vendored
14
.obsidian/workspace.json
vendored
@@ -4,21 +4,21 @@
|
||||
"type": "split",
|
||||
"children": [
|
||||
{
|
||||
"id": "90d0925ab4ee2d0c",
|
||||
"id": "1b63d80607fcf1ef",
|
||||
"type": "tabs",
|
||||
"children": [
|
||||
{
|
||||
"id": "3b843e69b2a87354",
|
||||
"id": "ab1a9c31dcf2580f",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "markdown",
|
||||
"state": {
|
||||
"file": "conflict-files-obsidian-git.md",
|
||||
"file": "TERCERO/SS/SS 24-25.md",
|
||||
"mode": "source",
|
||||
"source": false
|
||||
},
|
||||
"icon": "lucide-file",
|
||||
"title": "conflict-files-obsidian-git"
|
||||
"title": "SS 24-25"
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -175,17 +175,17 @@
|
||||
"obsidian-advanced-slides:Show Slide Preview": false
|
||||
}
|
||||
},
|
||||
"active": "3b843e69b2a87354",
|
||||
"active": "ab1a9c31dcf2580f",
|
||||
"lastOpenFiles": [
|
||||
"TERCERO/SPD/Teoría_2425.md",
|
||||
"TERCERO/SPD/P4_SPD.md",
|
||||
"conflict-files-obsidian-git.md",
|
||||
"TERCERO/SS/images/Pasted image 20241024113018.png",
|
||||
"TERCERO/SS/images/Pasted image 20241024090239.png",
|
||||
"TERCERO/SPD/Teoría_2425.md",
|
||||
"TERCERO/SPD/Guión Practica 4 SPD.md",
|
||||
"TERCERO/SPD/P4_SPD_Presentacion.md",
|
||||
"TERCERO/SPD/images/Pasted image 20241022144832.png",
|
||||
"TERCERO/SPD/images/Pasted image 20241022150214.png",
|
||||
"TERCERO/SPD/P4_SPD.md",
|
||||
"TERCERO/SPD/images/Pasted image 20241022144429.png",
|
||||
"TERCERO/SPD/images/Pasted image 20241022134454.png",
|
||||
"TERCERO/SPD/images/Pasted image 20240930084659.png",
|
||||
|
||||
@@ -1,83 +0,0 @@
|
||||
# <mark style="background: #FF5582A6;">ASM / C</mark>
|
||||
### a) ¿Qué hace el código?
|
||||
Recorre el array `arrayx` (empezando por la posición 1) de tamaño `N_ITER` almacenando en la posición `i - 1` la suma del elemento `i` más el `i + 1` entre la constante `f11`.
|
||||
### b) ¿Cómo se puede escribir en alto nivel?
|
||||
```C
|
||||
#define N_ITER 25
|
||||
|
||||
float arrayx[N_ITER];
|
||||
const float f11 = 21.0;
|
||||
|
||||
for(int i = 1; i < N_ITER; i++)
|
||||
{
|
||||
arrayx[i - 1] = ( arrayx[i] + arrayx[i + 1] ) / f11;
|
||||
}
|
||||
```
|
||||
### c) ¿Son paralelizables directamente?
|
||||
Sí porque no hay dependencias reales.
|
||||
```C
|
||||
#define N_ITER 25
|
||||
|
||||
float arrayx[N_ITER];
|
||||
const float f11 = 21.0;
|
||||
|
||||
for(int i = 5; i < N_ITER; i+=5)
|
||||
{
|
||||
arrayx[i - 1] = ( arrayx[i] + arrayx[i + 1] ) / f11;
|
||||
arrayx[i - 2] = ( arrayx[i + 1] + arrayx[i + 2] ) / f11;
|
||||
arrayx[i - 3] = ( arrayx[i + 2] + arrayx[i + 3] ) / f11;
|
||||
arrayx[i - 4] = ( arrayx[i + 3] + arrayx[i + 4] ) / f11;
|
||||
arrayx[i - 5] = ( arrayx[i + 4] + arrayx[i + 5] ) / f11;
|
||||
}
|
||||
```
|
||||
### d) Como la BTB predice siempre tomado ¿cuándo acierta?
|
||||
La BTB acertará en todas las iteraciones del bucle excepto en la última porque predice salto tomado y no debería tomarlo porque el bucle ha acabado.
|
||||
![[Pasted image 20241022134454.png]]
|
||||
### e) Si la BTB de un GPP es muy sofisticada ¿acertará en los saltos?
|
||||
...
|
||||
# <mark style="background: #D2B3FFA6;">Visual Studio</mark>
|
||||
La función más paralelizable es **`pp4()`** ya que sólo tiene una operación de cada tipo (**`LD, SF, ADDF, SLTI, ADDI`**) y no hay saltos condicionales en el bucle.
|
||||
```C
|
||||
double pp4()
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i<N_ITER; i++) {
|
||||
a[i] = a[i] + 8.0;
|
||||
}
|
||||
return a[N_ITER - 1];
|
||||
}
|
||||
```
|
||||
|
||||
La función que más se parece (parecer en términos de mismo tipo de instrucciones) es **`pp2()`**.
|
||||
```C
|
||||
double pp2()
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i<N_ITER; i++) {
|
||||
a[i] = 3.14 / sqrt(b[i]+c[i]);
|
||||
}
|
||||
return a[N_ITER - 1];
|
||||
}
|
||||
```
|
||||
|
||||
### <mark style="background: #FFB8EBA6;">Máquina en la que se ejecuta el código real:</mark>
|
||||
|
||||
![[Pasted image 20241022144429.png|400]]
|
||||
|
||||
### <mark style="background: #FFB8EBA6;">Comparativa</mark>
|
||||
|
||||
| `pp2()` | `nuestro` |
|
||||
| -------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| double pp2()<br>{<br> int i;<br> for (i = 0; i<N_ITER; i++) {<br> a[i] = 3.14 / sqrt(b[i]+c[i]);<br> }<br> return a[N_ITER - 1];<br>} | # define N_ITER 25<br><br>float arrayx[N_ITER];<br>const float f11 = 21.0;<br><br>for(int i = 1; i < N_ITER; i++)<br>{<br> arrayx[i - 1] = ( arrayx[i] + arrayx[i + 1] ) / f11; <br>} |
|
||||
| Este código tiene:<br>- 2x LDF<br>- 1x STF<br>- 1x ADDF<br>- 1x DIVF<br>- 1x constante | Nuestro código tiene:<br>- 2x LDF<br>- 1x STF<br>- 1x ADDF<br>- 1x DIVF<br>- 1x constante |
|
||||
| | |
|
||||
### <mark style="background: #FFB8EBA6;">Duración de CPI en los bucles</mark>
|
||||
|
||||
| Release | Debug |
|
||||
| ------------------------------------ | ------------------------------------ |
|
||||
| ![[Pasted image 20241022144832.png]] | ![[Pasted image 20241022150214.png]] |
|
||||
|
||||
(Todo para config1 y config2)
|
||||
5. GFLOPS (o MIPS)
|
||||
6. CPI (pp2 pp4) y Ac
|
||||
7. Cronograma
|
||||
@@ -226,21 +226,74 @@ En C/C++ parece fácil: usándolo. La mayoría de SO están escritos en C así q
|
||||
- Funciones terminadas en W (`MessageBoxW`)
|
||||
### <mark style="background: #FFB86CA6;">Tratamiento de errores</mark>
|
||||
Las funciones devuelven un entero, y si este es negativo es que ha terminado con error. Para más información sobre el error se usa `GetLastError()` y para mensajes al usuario `FormatMessage()`.
|
||||
# <mark style="background: #FFF3A3A6;">TEMA 5: Control de ejecución: procesos e hilos</mark>
|
||||
En Windows todos los procesos tienen al menos el "main thread". El programa termina cuando termina el hilo principal. Dos modelos básicos:
|
||||
- **Multihilo:** cada proceso tiene múltiples hilos. Típico de Windows aunque se usa cada vez más en UNIX/Linux.
|
||||
# <mark style="background: #FFF3A3A6;">TEMA 5: Control de ejecución: procesos e threads</mark>
|
||||
En Windows todos los procesos tienen al menos el "main thread". El programa termina cuando termina el thread principal. Dos modelos básicos:
|
||||
- **Multithread:** cada proceso tiene múltiples threads. Típico de Windows aunque se usa cada vez más en UNIX/Linux.
|
||||
- **Multiproceso:** múltiples procesos. Típico de UNIX/Linux, aunque también se puede en Windows. En Linux es **muy fácil** usando `fork()`.
|
||||
## <mark style="background: #ADCCFFA6;">1. Operaciones básicas con hilos</mark>
|
||||
Organizar la ejecución en varios hilos **¿para qué?**
|
||||
## <mark style="background: #ADCCFFA6;">1. Operaciones básicas con threads</mark>
|
||||
Organizar la ejecución en varios threads **¿para qué?**
|
||||
EJEMPLO: Programa de proceso de audio
|
||||
- **Hilo 1:** lee datos de la entrada de audio, los procesa y envía el resultado a la salida.
|
||||
- **thread 1:** lee datos de la entrada de audio, los procesa y envía el resultado a la salida.
|
||||
- Periódico
|
||||
- Intensivo en datos
|
||||
- Requiere velocidad de proceso
|
||||
- **WORKER THREADS**
|
||||
- **Hilo 2:** controla la UI (subir, bajar volumen, play, pause...) Complicado si alguna tarea es bloqueante.
|
||||
- **thread 2:** controla la UI (subir, bajar volumen, play, pause...) Complicado si alguna tarea es bloqueante.
|
||||
- No periódico
|
||||
- No intensivo
|
||||
- No requiere velocidad de proceso
|
||||
- **USER INTERFACE THREAD**
|
||||
-
|
||||
### <mark style="background: #FFB86CA6;">Crear un thread</mark>
|
||||
En Windows se usa `CreateThread()` que devuelve un `HANDLE`. Los elementos que integran el thread son:
|
||||
- Función de entrada
|
||||
- Parámetro(s)
|
||||
- Pila
|
||||
- Almacenamiento local al thread
|
||||
- El HANDLE y el ID
|
||||
Los threads son **asíncronos**.
|
||||
#### <mark style="background: #D2B3FFA6;">Ejemplo</mark>
|
||||
```C
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
setlocale(LC_ALL, "Spanish");
|
||||
|
||||
DWORD Ciclo = 1000; // Ciclo entre pitidos (en ms)
|
||||
DWORD Frecuencia = 500;
|
||||
DWORD Duracion = 100;
|
||||
|
||||
while (TRUE){
|
||||
// bip a frec. y duración que se le pasa
|
||||
Beep(Frecuencia, Duracion);
|
||||
Sleep(Ciclo);
|
||||
}
|
||||
|
||||
printf("\nPulse tecla RETORNO para terminar\n");
|
||||
getchar(); // bloqueo
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
Para evitar el bloqueo, en C++ existen alternativas (en C **NO**), como `std::thread` o `std::async`.
|
||||
### <mark style="background: #FFB86CA6;">Suspender/Reactivar un thread</mark>
|
||||
El thread se puede suspender o reactivar usando respectivamente `SuspendThread` y `ResumeThread`. El thread está suspendido si el contador != 0.
|
||||
### <mark style="background: #FFB86CA6;">Terminar un thread</mark>
|
||||
Un thread finaliza cuando termina su función de entrada, cuando se termina a sí mismo con `ExitThread` o cuando lo "terminan" con `TerminateThread`.
|
||||
## <mark style="background: #ADCCFFA6;">2. Organización de los datos en un thread</mark>
|
||||
Los hilos comparten variables globales y código. También pueden pasarse punteros (posibilidad de errores).
|
||||
### <mark style="background: #FFB86CA6;">Código reentrante</mark>
|
||||
Código que puede ser usado desde más de un hilo. Se puede aplicar a:
|
||||
- Código completo del hilo
|
||||
- Algunas funciones
|
||||
- Bibliotecas
|
||||
Cada instancia de un thread tiene sus propios recursos, los cuales hay que proteger con mecanismos de control de la concurrencia.
|
||||
## <mark style="background: #ADCCFFA6;">3. Creando procesos</mark>
|
||||
`CreateProcess` crea un proceso concurrente. Algunos puntos a destacar en la descripción de `CreateProcess`:
|
||||
- **`IpApplicationName`**: es opcional. Si es `NULL`, el nombre del programa se incluye en el siguiente parámetro.
|
||||
- **`IpCommandLine`**: si el path del ejecutable no está, se sigue la secuencia de búsqueda que viene al final de este parámetro.
|
||||
- **`IpProcessAttributes, IpThreadAttributes, bInheritHandles, IpEnvironment, IpCurrentDirectory`**: <strong style="color:red;">no los usaremos</strong>, poner a NULL/FALSE.
|
||||
- **`IpStartupInfo`**: la estructura `STARTUPINFO` <strong style="color:red;">no la usaremos</strong> pero tiene que estar.
|
||||
- **`IpProcessInformation`**: rellena la estructura `PROCESS_INFORMATION` con información sobre el proceso y thread creado (handles, process/threads ids).
|
||||
## <mark style="background: #ADCCFFA6;">4. Punto de vista de la programación y procesos POSIX</mark>
|
||||
- Aunque el proceso creado se le llama "hijo" **no hay relación lógica** entre ambos, al menos en Windows. En UNIX/Linux/POSIX **sí hay**.
|
||||
- La creación del proceso es asíncrona, **NO** es una "llamada".
|
||||
- En la biblioteca de C: `exec` (UNIX) / `_exec` (Win) funcionan distinto en Windows y UNIX/Linux. En Windows se basa en `CreateProcess` y en UNIX/Linux el proceso actual carga un nuevo programa:
|
||||
- `posix spawn` es lo equivalente a `CreateProcess` que básicamente hace: `fork` + `exec`
|
||||
@@ -1,17 +0,0 @@
|
||||
# Conflicts
|
||||
Please resolve them and commit them using the commands `Git: Commit all changes` followed by `Git: Push`
|
||||
(This file will automatically be deleted before commit)
|
||||
[[#Additional Instructions]] available below file list
|
||||
|
||||
- Not a file: .obsidian/workspace.json
|
||||
|
||||
# Additional Instructions
|
||||
I strongly recommend to use "Source mode" for viewing the conflicted files. For simple conflicts, in each file listed above replace every occurrence of the following text blocks with the desired text.
|
||||
|
||||
```diff
|
||||
<<<<<<< HEAD
|
||||
File changes in local repository
|
||||
=======
|
||||
File changes in remote repository
|
||||
>>>>>>> origin/main
|
||||
```
|
||||
Reference in New Issue
Block a user