-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmultescalar-avx.c
81 lines (63 loc) · 2.97 KB
/
multescalar-avx.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
/**
* Este código fue desarrollado en colaboración con ChatGPT
* Fecha: 05/03/2024
* Autor: John Sanabria - [email protected]
*/
#include <immintrin.h> // Esta librer proporciona funciones para operaciones intrínsecas de vectores en C.
#include <stdio.h> // Esta librería permite operaciones de entrada/salida estándar, como printf y scanf.
#include <assert.h> // Esta librería proporciona la macro assert, se utiliza para realizar verificaciones en tiempo de ejecución.
#define VECTORSIZE 4 // Define el tamaño del vector como 4.
// Función para realizar la multiplicación de un vector por un escalar utilizando AVX instrucciones
void vectorScalarMultiply(const double* vector, double scalar, double* result, int length) {
// Asegura que el length sea múltiplo de 4 para un alineamiento adecuado.
int alignedLength = (length + 3) & ~3;
// Itera a través del vector en bloques de 4 elementos.
for (int i = 0; i < alignedLength; i += 4) {
// Carga el bloque del vector en un registro AVX.
__m256d vec = _mm256_loadu_pd(vector + i);
// Transmite el valor escalar a todos los elementos de otro registro AVX.
__m256d scalarVec = _mm256_broadcast_sd(&scalar);
// Realiza la multiplicación elemento a elemento.
__m256d resultVec = _mm256_mul_pd(vec, scalarVec);
// Almacena el resultado en memoria.
_mm256_storeu_pd(result + i, resultVec);
}
}
int main(int argc, char* argv[]) {
// Datos de ejemplo.
int vectorSize;
double *vector;
double scalar = 2.0;
double *result;
if (argc == 1) {
vectorSize = VECTORSIZE;
} else {
vectorSize = atoi(argv[1]);
}
vector = (double*)malloc(sizeof(double)*vectorSize);
assert(vector != NULL); // Verifica si la asignación de memoria ha sido exitosa.
result = (double*)malloc(sizeof(double)*vectorSize);
assert(result != NULL); // Verifica si la asignación de memoria ha sido exitosa.
// Inicializa el vector con algunos valores.
for (int i = 0; i < vectorSize; ++i) {
vector[i] = i + 1; // Llena el vector con valores, comenzando desde 1.
}
// Realiza la multiplicación vector-escalar utilizando la función definida anteriormente.
vectorScalarMultiply(vector, scalar, result, vectorSize);
// Imprime el resultado.
#ifdef DEBUG
printf("Vector Original:\n");
for (int i = 0; i < vectorSize; ++i) {
printf("%lf ", vector[i]); // Imprime los valores del vector original.
}
printf("\nEscalar: %lf\n", scalar); // Imprime el valor del escalar.
printf("Resultado:\n");
for (int i = 0; i < vectorSize; ++i) {
printf("%lf ", result[i]); // Imprime los valores del vector resultante.
}
#endif
// Libera la memoria asignada dinámicamente.
free(vector);
free(result);
return 0; // Devuelve 0 para indicar una ejecución exitosa.
}