parent
a62c3001dc
commit
a8c42927e8
@ -0,0 +1,130 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <arm_neon.h>
|
||||||
|
|
||||||
|
// 基础向量加法
|
||||||
|
void vector_add_base(float *a, float *b, float *c, int n) {
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
c[i] = a[i] + b[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NEON优化向量加法
|
||||||
|
void vector_add_neon(float *a, float *b, float *c, int n) {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i <= n - 4; i += 4) {
|
||||||
|
float32x4_t va = vld1q_f32(&a[i]);
|
||||||
|
float32x4_t vb = vld1q_f32(&b[i]);
|
||||||
|
float32x4_t vc = vaddq_f32(va, vb);
|
||||||
|
vst1q_f32(&c[i], vc);
|
||||||
|
}
|
||||||
|
for (; i < n; i++) {
|
||||||
|
c[i] = a[i] + b[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 基础矩阵乘法
|
||||||
|
void matrix_multiply_base(float *A, float *B, float *C, int N) {
|
||||||
|
for (int i = 0; i < N; i++) {
|
||||||
|
for (int j = 0; j < N; j++) {
|
||||||
|
float sum = 0.0f;
|
||||||
|
for (int k = 0; k < N; k++) {
|
||||||
|
sum += A[i * N + k] * B[k * N + j];
|
||||||
|
}
|
||||||
|
C[i * N + j] = sum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NEON优化矩阵乘法
|
||||||
|
void matrix_multiply_neon(float *A, float *B, float *C, int N) {
|
||||||
|
int i, j, k;
|
||||||
|
for (i = 0; i < N; i++) {
|
||||||
|
for (j = 0; j < N; j++) {
|
||||||
|
float32x4_t sum = vdupq_n_f32(0.0f);
|
||||||
|
for (k = 0; k <= N - 4; k += 4) {
|
||||||
|
float32x4_t va = vld1q_f32(&A[i * N + k]);
|
||||||
|
float32x4_t vb = vld1q_f32(&B[k * N + j]);
|
||||||
|
sum = vmlaq_f32(sum, va, vb);
|
||||||
|
}
|
||||||
|
C[i * N + j] = vgetq_lane_f32(sum, 0) + vgetq_lane_f32(sum, 1) +
|
||||||
|
vgetq_lane_f32(sum, 2) + vgetq_lane_f32(sum, 3);
|
||||||
|
|
||||||
|
// 处理剩余的元素
|
||||||
|
for (; k < N; k++) {
|
||||||
|
C[i * N + j] += A[i * N + k] * B[k * N + j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化矩阵
|
||||||
|
void initialize_matrix(float *matrix, int N) {
|
||||||
|
for (int i = 0; i < N * N; i++) {
|
||||||
|
matrix[i] = (float)(rand() % 100) / 100.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算时间
|
||||||
|
double get_time() {
|
||||||
|
struct timespec ts;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||||
|
return ts.tv_sec + ts.tv_nsec * 1e-9;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
int N = 1024; // 矩阵大小
|
||||||
|
float *a, *b, *c, *A, *B, *C;
|
||||||
|
|
||||||
|
// 分配内存
|
||||||
|
a = (float *)aligned_alloc(16, N * sizeof(float));
|
||||||
|
b = (float *)aligned_alloc(16, N * sizeof(float));
|
||||||
|
c = (float *)aligned_alloc(16, N * sizeof(float));
|
||||||
|
A = (float *)aligned_alloc(16, N * N * sizeof(float));
|
||||||
|
B = (float *)aligned_alloc(16, N * N * sizeof(float));
|
||||||
|
C = (float *)aligned_alloc(16, N * N * sizeof(float));
|
||||||
|
|
||||||
|
// 初始化向量和矩阵
|
||||||
|
for (int i = 0; i < N; i++) {
|
||||||
|
a[i] = (float)(rand() % 100) / 100.0f;
|
||||||
|
b[i] = (float)(rand() % 100) / 100.0f;
|
||||||
|
}
|
||||||
|
initialize_matrix(A, N);
|
||||||
|
initialize_matrix(B, N);
|
||||||
|
|
||||||
|
// 基础向量加法
|
||||||
|
double start_time = get_time();
|
||||||
|
vector_add_base(a, b, c, N);
|
||||||
|
double end_time = get_time();
|
||||||
|
printf("基础向量加法时间: %.6f 秒\n", end_time - start_time);
|
||||||
|
|
||||||
|
// NEON优化向量加法
|
||||||
|
start_time = get_time();
|
||||||
|
vector_add_neon(a, b, c, N);
|
||||||
|
end_time = get_time();
|
||||||
|
printf("NEON优化向量加法时间: %.6f 秒\n", end_time - start_time);
|
||||||
|
|
||||||
|
// 基础矩阵乘法
|
||||||
|
start_time = get_time();
|
||||||
|
matrix_multiply_base(A, B, C, N);
|
||||||
|
end_time = get_time();
|
||||||
|
printf("基础矩阵乘法时间: %.6f 秒\n", end_time - start_time);
|
||||||
|
|
||||||
|
// NEON优化矩阵乘法
|
||||||
|
start_time = get_time();
|
||||||
|
matrix_multiply_neon(A, B, C, N);
|
||||||
|
end_time = get_time();
|
||||||
|
printf("NEON优化矩阵乘法时间: %.6f 秒\n", end_time - start_time);
|
||||||
|
|
||||||
|
// 释放内存
|
||||||
|
free(a);
|
||||||
|
free(b);
|
||||||
|
free(c);
|
||||||
|
free(A);
|
||||||
|
free(B);
|
||||||
|
free(C);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in new issue