-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathq2.c
More file actions
78 lines (59 loc) · 1.93 KB
/
Copy pathq2.c
File metadata and controls
78 lines (59 loc) · 1.93 KB
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
#include <stdio.h>
#include <stdlib.h>
#include <immintrin.h>
typedef enum {
VEC_SUCCESS = 0,
VEC_ERR_NULL_PTR = -1,
VEC_ERR_OUT_OF_MEMORY = -2,
VEC_ERR_SIZE_MISMATCH = -3,
VEC_ERR_INVALID_ALIGNMENT = -4
} VecError;
typedef struct {
size_t size;
size_t alignment;
double* data;
} AlignedVector;
void aligned_vector_destroy(AlignedVector* vec) {
if (vec != NULL) {
if (vec->data != NULL) {
free(vec->data);
vec->data = NULL;
}
vec->size = 0;
vec->alignment = 0;
}
}
VecError aligned_vector_create(AlignedVector* vec, size_t size, size_t alignment) {
if (vec == NULL) return VEC_ERR_NULL_PTR;
if ((alignment == 0) || (alignment & (alignment - 1)) != 0) {
return VEC_ERR_INVALID_ALIGNMENT;
}
vec->size = size;
vec->alignment = alignment;
size_t byte_size = size * sizeof(double);
size_t padded_size = (byte_size + alignment - 1) & ~(alignment - 1);
vec->data = (double*)aligned_alloc(alignment, padded_size);
if (vec->data == NULL) {
aligned_vector_destroy(vec);
return VEC_ERR_OUT_OF_MEMORY;
}
return VEC_SUCCESS;
}
VecError vector_add_avx2(const AlignedVector* A, const AlignedVector* B, AlignedVector* C) {
if (!A || !B || !C || !A->data || !B->data || !C->data) return VEC_ERR_NULL_PTR;
if (A->size != B->size || A->size != C->size) return VEC_ERR_SIZE_MISMATCH;
if (A->alignment < 32 || B->alignment < 32 || C->alignment < 32) {
return VEC_ERR_INVALID_ALIGNMENT;
}
size_t i = 0;
for (; i + 3 < A->size; i += 4) {
__m256d vec_a = _mm256_load_pd(&A->data[i]);
__m256d vec_b = _mm256_load_pd(&B->data[i]);
__m256d vec_c = _mm256_add_pd(vec_a, vec_b);
_mm256_store_pd(&C->data[i], vec_c);
}
for (; i < A->size; ++i) {
C->data[i] = A->data[i] + B->data[i];
}
return VEC_SUCCESS;
}