Compare commits
6 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
83991e7f8e | 1 year ago |
|
|
52f1c628a0 | 1 year ago |
|
|
9843c26a75 | 1 year ago |
|
|
523e2aed15 | 1 year ago |
|
|
8fe739a87f | 1 year ago |
|
|
7742704b35 | 1 year ago |
@ -0,0 +1,129 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <arm_neon.h> // 包含 NEON 头文件
|
||||
|
||||
#define SIZE 1024 // 定义矩阵大小
|
||||
#define ALIGNMENT 16 // NEON要求的数据对齐
|
||||
|
||||
// 动态分配对齐的二维数组
|
||||
float** allocate_2d_array(int rows, int cols) {
|
||||
float** array = (float**)malloc(rows * sizeof(float*));
|
||||
if (!array) {
|
||||
fprintf(stderr, "Memory allocation failed for 2D array.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
for (int i = 0; i < rows; ++i) {
|
||||
array[i] = (float*)aligned_alloc(ALIGNMENT, cols * sizeof(float));
|
||||
if (!array[i]) {
|
||||
fprintf(stderr, "Memory allocation failed for row %d.\n", i);
|
||||
// 释放已经分配的内存
|
||||
for (int j = 0; j < i; ++j) {
|
||||
free(array[j]);
|
||||
}
|
||||
free(array);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
// 释放二维数组
|
||||
void free_2d_array(float** array, int rows) {
|
||||
for (int i = 0; i < rows; ++i) {
|
||||
free(array[i]);
|
||||
}
|
||||
free(array);
|
||||
}
|
||||
|
||||
// 基础矩阵乘法函数
|
||||
void matmul(float** A, float** B, float** C, int n) {
|
||||
for (int i = 0; i < n; ++i) {
|
||||
for (int j = 0; j < n; ++j) {
|
||||
C[i][j] = 0; // 初始化 C[i][j]
|
||||
for (int k = 0; k < n; ++k) {
|
||||
C[i][j] += A[i][k] * B[k][j]; // 逐项累加计算结果
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NEON 优化矩阵乘法函数
|
||||
void matmul_optimized(float** A, float** B, float** C, int n) {
|
||||
for (int i = 0; i < n; ++i) {
|
||||
for (int j = 0; j < n; ++j) {
|
||||
float32x4_t vecC = vdupq_n_f32(0.0); // 初始化结果向量 vecC 为 0
|
||||
|
||||
for (int k = 0; k <= n - 4; k += 4) { // 确保不会越界
|
||||
// 加载矩阵 A 和 B 的 4 个连续元素
|
||||
float32x4_t vecA = vld1q_f32(&A[i][k]);
|
||||
float32x4_t vecB = vld1q_f32(&B[k][j]);
|
||||
|
||||
// 执行向量化乘法和累加
|
||||
vecC = vmlaq_f32(vecC, vecA, vecB);
|
||||
}
|
||||
|
||||
// 还原向量结果到 C[i][j]
|
||||
C[i][j] = vaddvq_f32(vecC);
|
||||
|
||||
// 处理剩余元素(如果 n 不是 4 的倍数)
|
||||
for (int k = n & ~3; k < n; ++k) {
|
||||
C[i][j] += A[i][k] * B[k][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
// 检查是否支持NEON
|
||||
#if !defined(__ARM_NEON)
|
||||
printf("Error: This compiler does not support ARM NEON.\n");
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
// 动态分配矩阵 A、B、C 和 C_optimized 的内存
|
||||
float** A = allocate_2d_array(SIZE, SIZE);
|
||||
float** B = allocate_2d_array(SIZE, SIZE);
|
||||
float** C = allocate_2d_array(SIZE, SIZE);
|
||||
float** C_optimized = allocate_2d_array(SIZE, SIZE);
|
||||
|
||||
// 初始化矩阵 A 和 B 的元素
|
||||
srand(time(0));
|
||||
for (int i = 0; i < SIZE; ++i) {
|
||||
for (int j = 0; j < SIZE; ++j) {
|
||||
A[i][j] = rand() % 100; // 生成 0 到 99 的随机数
|
||||
B[i][j] = rand() % 100;
|
||||
}
|
||||
}
|
||||
|
||||
// 计时并进行基础矩阵乘法
|
||||
clock_t start = clock();
|
||||
matmul(A, B, C, SIZE); // 执行基础矩阵乘法
|
||||
clock_t end = clock();
|
||||
printf("基础矩阵乘法运行时间: %.6f 秒\n", (double)(end - start) / CLOCKS_PER_SEC);
|
||||
|
||||
// 计时并进行 NEON 优化矩阵乘法
|
||||
start = clock();
|
||||
matmul_optimized(A, B, C_optimized, SIZE); // 执行 NEON 优化矩阵乘法
|
||||
end = clock();
|
||||
printf("NEON 优化矩阵乘法运行时间: %.6f 秒\n", (double)(end - start) / CLOCKS_PER_SEC);
|
||||
|
||||
// 验证结果
|
||||
for (int i = 0; i < SIZE; ++i) {
|
||||
for (int j = 0; j < SIZE; ++j) {
|
||||
if (C[i][j] != C_optimized[i][j]) {
|
||||
printf("Results do not match at index (%d, %d): %f vs %f\n", i, j, C[i][j], C_optimized[i][j]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 释放矩阵 A、B、C、C_optimized 的内存
|
||||
free_2d_array(A, SIZE);
|
||||
free_2d_array(B, SIZE);
|
||||
free_2d_array(C, SIZE);
|
||||
free_2d_array(C_optimized, SIZE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -0,0 +1,105 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
// 定义稀疏矩阵的结构体
|
||||
typedef struct {
|
||||
float* values; // 存储非零元素的值
|
||||
int* rowIndex; // 存储非零元素的行索引
|
||||
int* colIndex; // 存储非零元素的列索引
|
||||
int nonZeroCount; // 非零元素的总数量
|
||||
int rows; // 矩阵的总行数
|
||||
int cols; // 矩阵的总列数
|
||||
} SparseMatrix;
|
||||
|
||||
// 初始化稀疏矩阵
|
||||
SparseMatrix create_sparse_matrix(int rows, int cols, int nonZeroCount) {
|
||||
SparseMatrix mat;
|
||||
mat.values = (float*)malloc(nonZeroCount * sizeof(float));
|
||||
mat.rowIndex = (int*)malloc(nonZeroCount * sizeof(int));
|
||||
mat.colIndex = (int*)malloc(nonZeroCount * sizeof(int));
|
||||
mat.nonZeroCount = nonZeroCount;
|
||||
mat.rows = rows;
|
||||
mat.cols = cols;
|
||||
return mat;
|
||||
}
|
||||
|
||||
// 释放稀疏矩阵内存
|
||||
void free_sparse_matrix(SparseMatrix* mat) {
|
||||
free(mat->values);
|
||||
free(mat->rowIndex);
|
||||
free(mat->colIndex);
|
||||
}
|
||||
|
||||
// 稀疏矩阵乘法
|
||||
void sparse_matmul(SparseMatrix* A, SparseMatrix* B, SparseMatrix* C) {
|
||||
// 假设 A 的列数等于 B 的行数
|
||||
for (int i = 0; i < A->nonZeroCount; ++i) {
|
||||
for (int j = 0; j < B->nonZeroCount; ++j) {
|
||||
// 如果 A 的列索引和 B 的行索引相同
|
||||
if (A->colIndex[i] == B->rowIndex[j]) {
|
||||
int row = A->rowIndex[i];
|
||||
int col = B->colIndex[j];
|
||||
// 更新结果矩阵
|
||||
for (int k = 0; k < C->nonZeroCount; ++k) {
|
||||
if (C->rowIndex[k] == row && C->colIndex[k] == col) {
|
||||
C->values[k] += A->values[i] * B->values[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 打印稀疏矩阵
|
||||
void print_sparse_matrix(SparseMatrix* mat) {
|
||||
printf("Sparse Matrix:\n");
|
||||
for (int i = 0; i < mat->nonZeroCount; ++i) {
|
||||
printf("Value: %f, Row: %d, Col: %d\n", mat->values[i], mat->rowIndex[i], mat->colIndex[i]);
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
// 初始化稀疏矩阵 A 和 B
|
||||
int rows = 4, cols = 4, nonZeroCountA = 4, nonZeroCountB = 4;
|
||||
SparseMatrix A = create_sparse_matrix(rows, cols, nonZeroCountA);
|
||||
SparseMatrix B = create_sparse_matrix(rows, cols, nonZeroCountB);
|
||||
|
||||
// 初始化 A 和 B 矩阵中的非零元素
|
||||
srand(time(0));
|
||||
for (int i = 0; i < nonZeroCountA; ++i) {
|
||||
A.values[i] = rand() % 10 + 1;
|
||||
A.rowIndex[i] = i % rows; // 为了简化,这里使用简单的模式
|
||||
A.colIndex[i] = i % cols;
|
||||
}
|
||||
for (int i = 0; i < nonZeroCountB; ++i) {
|
||||
B.values[i] = rand() % 10 + 1;
|
||||
B.rowIndex[i] = i % rows; // 为了简化,这里使用简单的模式
|
||||
B.colIndex[i] = i % cols;
|
||||
}
|
||||
|
||||
// 初始化结果矩阵 C
|
||||
SparseMatrix C = create_sparse_matrix(rows, cols, nonZeroCountA * nonZeroCountB); // 最坏情况下的非零元素数量
|
||||
for (int i = 0; i < C.nonZeroCount; ++i) {
|
||||
C.values[i] = 0;
|
||||
C.rowIndex[i] = -1; // 标记为未使用
|
||||
C.colIndex[i] = -1;
|
||||
}
|
||||
|
||||
// 计时并进行稀疏矩阵乘法
|
||||
clock_t start = clock();
|
||||
sparse_matmul(&A, &B, &C); // 执行稀疏矩阵乘法
|
||||
clock_t end = clock();
|
||||
printf("稀疏矩阵乘法运行时间: %.6f 秒\n", (double)(end - start) / CLOCKS_PER_SEC);
|
||||
|
||||
// 打印结果矩阵
|
||||
print_sparse_matrix(&C);
|
||||
|
||||
// 释放稀疏矩阵 A、B、C 的内存
|
||||
free_sparse_matrix(&A);
|
||||
free_sparse_matrix(&B);
|
||||
free_sparse_matrix(&C);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -0,0 +1,133 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
// 定义稀疏矩阵的结构体
|
||||
typedef struct {
|
||||
float* values; // 存储非零元素的值
|
||||
int* rowIndex; // 存储非零元素的行索引
|
||||
int* colIndex; // 存储非零元素的列索引
|
||||
int nonZeroCount; // 非零元素的总数量
|
||||
int rows; // 矩阵的总行数
|
||||
int cols; // 矩阵的总列数
|
||||
} SparseMatrix;
|
||||
|
||||
// 初始化稀疏矩阵
|
||||
SparseMatrix create_sparse_matrix(int rows, int cols, int nonZeroCount) {
|
||||
SparseMatrix mat;
|
||||
mat.values = (float*)malloc(nonZeroCount * sizeof(float));
|
||||
mat.rowIndex = (int*)malloc(nonZeroCount * sizeof(int));
|
||||
mat.colIndex = (int*)malloc(nonZeroCount * sizeof(int));
|
||||
mat.nonZeroCount = nonZeroCount;
|
||||
mat.rows = rows;
|
||||
mat.cols = cols;
|
||||
return mat;
|
||||
}
|
||||
|
||||
// 释放稀疏矩阵内存
|
||||
void free_sparse_matrix(SparseMatrix* mat) {
|
||||
free(mat->values);
|
||||
free(mat->rowIndex);
|
||||
free(mat->colIndex);
|
||||
}
|
||||
|
||||
// 将稀疏矩阵转换为普通矩阵
|
||||
void sparse_to_dense(SparseMatrix* sparse, float** denseMatrix) {
|
||||
int i, j;
|
||||
for (i = 0; i < sparse->rows; ++i) {
|
||||
for (j = 0; j < sparse->cols; ++j) {
|
||||
denseMatrix[i][j] = 0; // 初始化为零
|
||||
}
|
||||
}
|
||||
for (i = 0; i < sparse->nonZeroCount; ++i) {
|
||||
denseMatrix[sparse->rowIndex[i]][sparse->colIndex[i]] = sparse->values[i];
|
||||
}
|
||||
}
|
||||
|
||||
// 稀疏矩阵乘法
|
||||
void sparse_matmul(SparseMatrix* A, SparseMatrix* B, SparseMatrix* C) {
|
||||
// 假设 A 的列数等于 B 的行数
|
||||
int i, j, k;
|
||||
// 遍历 A 和 B 的非零元素进行乘法累加
|
||||
for (i = 0; i < A->nonZeroCount; ++i) {
|
||||
for (j = 0; j < B->nonZeroCount; ++j) {
|
||||
// 如果 A 的列索引和 B 的行索引相同
|
||||
if (A->colIndex[i] == B->rowIndex[j]) {
|
||||
// 找到位置 (A->rowIndex[i], B->colIndex[j]) 更新结果矩阵
|
||||
for (k = 0; k < C->nonZeroCount; ++k) {
|
||||
if (C->rowIndex[k] == A->rowIndex[i] && C->colIndex[k] == B->colIndex[j]) {
|
||||
C->values[k] += A->values[i] * B->values[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
// 初始化稀疏矩阵 A 和 B
|
||||
int rows = 4, cols = 4, nonZeroCountA = 4, nonZeroCountB = 4, nonZeroCountC = 4;
|
||||
SparseMatrix A = create_sparse_matrix(rows, cols, nonZeroCountA);
|
||||
SparseMatrix B = create_sparse_matrix(rows, cols, nonZeroCountB);
|
||||
SparseMatrix C = create_sparse_matrix(rows, cols, nonZeroCountC);
|
||||
|
||||
// 初始化 A 和 B 矩阵中的非零元素
|
||||
// 这里仅做简单的初始化,可以根据需要填充实际数据
|
||||
srand(time(0));
|
||||
int i;
|
||||
for (i = 0; i < nonZeroCountA; ++i) {
|
||||
A.values[i] = rand() % 10 + 1;
|
||||
A.rowIndex[i] = rand() % rows;
|
||||
A.colIndex[i] = rand() % cols;
|
||||
}
|
||||
for (i = 0; i < nonZeroCountB; ++i) {
|
||||
B.values[i] = rand() % 10 + 1;
|
||||
B.rowIndex[i] = rand() % rows;
|
||||
B.colIndex[i] = rand() % cols;
|
||||
}
|
||||
|
||||
// 初始化结果矩阵 C 的非零元素为零
|
||||
for (i = 0; i < nonZeroCountC; ++i) {
|
||||
C.values[i] = 0;
|
||||
C.rowIndex[i] = rand() % rows; // 初始化索引,可能需要根据实际需求调整
|
||||
C.colIndex[i] = rand() % cols;
|
||||
}
|
||||
|
||||
// 将稀疏矩阵转换为普通矩阵
|
||||
float** denseMatrixA = (float**)malloc(rows * sizeof(float*));
|
||||
for (i = 0; i < rows; ++i) {
|
||||
denseMatrixA[i] = (float*)malloc(cols * sizeof(float));
|
||||
}
|
||||
sparse_to_dense(&A, denseMatrixA);
|
||||
|
||||
// 打印普通矩阵 A
|
||||
printf("\n普通矩阵 A:\n");
|
||||
for (i = 0; i < rows; ++i) {
|
||||
int j;
|
||||
for (j = 0; j < cols; ++j) {
|
||||
printf("%.2f ", denseMatrixA[i][j]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
// 计时并进行稀疏矩阵乘法
|
||||
clock_t start = clock();
|
||||
sparse_matmul(&A, &B, &C); // 执行稀疏矩阵乘法
|
||||
clock_t end = clock();
|
||||
printf("稀疏矩阵乘法运行时间: %.6f 秒\n", (double)(end - start) / CLOCKS_PER_SEC);
|
||||
|
||||
// 释放稀疏矩阵 A、B、C 的内存
|
||||
free_sparse_matrix(&A);
|
||||
free_sparse_matrix(&B);
|
||||
free_sparse_matrix(&C);
|
||||
|
||||
// 释放普通矩阵 A 的内存
|
||||
for (i = 0; i < rows; ++i) {
|
||||
free(denseMatrixA[i]);
|
||||
}
|
||||
free(denseMatrixA);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -0,0 +1,46 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
#define SIZE 1024
|
||||
|
||||
// 向量加法函数
|
||||
void vector_add(float* A, float* B, float* C, int size) {
|
||||
for (int i = 0; i < size; ++i) { // 在循环内部声明i
|
||||
C[i] = A[i] + B[i];
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
// 定义向量
|
||||
float A[SIZE], B[SIZE], C[SIZE];
|
||||
|
||||
// 初始化随机数种子
|
||||
srand(time(0));
|
||||
|
||||
// 初始化向量 A 和 B
|
||||
for (int i = 0; i < SIZE; ++i) { // 在循环内部声明i
|
||||
A[i] = (float)(rand() % 100) / 100.0f; // 生成0到1之间的浮点数
|
||||
B[i] = (float)(rand() % 100) / 100.0f;
|
||||
}
|
||||
|
||||
// 多次执行以获得更准确的时间测量
|
||||
const int NUM_ITERATIONS = 1000;
|
||||
clock_t total_time = 0;
|
||||
for (int j = 0; j < NUM_ITERATIONS; ++j) {
|
||||
clock_t start = clock();
|
||||
vector_add(A, B, C, SIZE); // 执行向量加法
|
||||
clock_t end = clock();
|
||||
total_time += (end - start);
|
||||
}
|
||||
出平
|
||||
// 输均运行时间
|
||||
printf("基础向量加法平均运行时间: %.6f 秒\n", (double)total_time / (CLOCKS_PER_SEC * NUM_ITERATIONS));
|
||||
|
||||
// 可选:验证前几个元素的结果
|
||||
for (int k = 0; k < 5; ++k) {
|
||||
printf("A[%d] + B[%d] = C[%d]: %.2f + %.2f = %.2f\n", k, k, k, A[k], B[k], C[k]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -0,0 +1,85 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
#define SIZE 1024 // 定义矩阵大小
|
||||
#define ALIGNMENT 64 // 对齐大小
|
||||
|
||||
// 动态分配对齐的二维数组
|
||||
float** allocate_2d_array(int rows, int cols) {
|
||||
float** array = (float**)malloc(rows * sizeof(float*));
|
||||
if (!array) {
|
||||
fprintf(stderr, "Memory allocation failed for 2D array.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
for (int i = 0; i < rows; ++i) {
|
||||
array[i] = (float*)aligned_alloc(ALIGNMENT, cols * sizeof(float));
|
||||
if (!array[i]) {
|
||||
fprintf(stderr, "Memory allocation failed for row %d.\n", i);
|
||||
// 释放已经分配的内存
|
||||
for (int j = 0; j < i; ++j) {
|
||||
free(array[j]);
|
||||
}
|
||||
free(array);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
// 释放二维数组
|
||||
void free_2d_array(float** array, int rows) {
|
||||
for (int i = 0; i < rows; ++i) {
|
||||
free(array[i]);
|
||||
}
|
||||
free(array);
|
||||
}
|
||||
|
||||
// 矩阵乘法函数
|
||||
void matmul(float** A, float** B, float** C, int n) {
|
||||
for (int i = 0; i < n; ++i) {
|
||||
for (int j = 0; j < n; ++j) {
|
||||
C[i][j] = 0; // 初始化 C[i][j]
|
||||
for (int k = 0; k < n; ++k) {
|
||||
C[i][j] += A[i][k] * B[k][j]; // 逐项累加计算结果
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
// 动态分配矩阵 A、B、C 的内存
|
||||
float** A = allocate_2d_array(SIZE, SIZE);
|
||||
float** B = allocate_2d_array(SIZE, SIZE);
|
||||
float** C = allocate_2d_array(SIZE, SIZE);
|
||||
|
||||
// 初始化矩阵 A 和 B 的元素
|
||||
srand(time(0));
|
||||
for (int i = 0; i < SIZE; ++i) {
|
||||
for (int j = 0; j < SIZE; ++j) {
|
||||
A[i][j] = rand() % 100; // 生成 0 到 99 的随机数
|
||||
B[i][j] = rand() % 100;
|
||||
}
|
||||
}
|
||||
|
||||
// 多次执行以获得更准确的时间测量
|
||||
const int NUM_ITERATIONS = 10;
|
||||
clock_t total_time = 0;
|
||||
for (int iter = 0; iter < NUM_ITERATIONS; ++iter) {
|
||||
clock_t start = clock();
|
||||
matmul(A, B, C, SIZE); // 执行矩阵乘法
|
||||
clock_t end = clock();
|
||||
total_time += (end - start);
|
||||
}
|
||||
|
||||
// 输出平均运行时间
|
||||
printf("基础矩阵乘法平均运行时间: %.6f 秒\n", (double)total_time / (CLOCKS_PER_SEC * NUM_ITERATIONS));
|
||||
|
||||
// 释放矩阵 A、B、C 的内存
|
||||
free_2d_array(A, SIZE);
|
||||
free_2d_array(B, SIZE);
|
||||
free_2d_array(C, SIZE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -0,0 +1,83 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <arm_neon.h> // 包含 NEON 头文件
|
||||
|
||||
#define SIZE 1024 // 定义向量大小
|
||||
#define ALIGNMENT 16 // NEON要求的数据对齐
|
||||
|
||||
// 基础向量加法函数
|
||||
void vector_add(float* A, float* B, float* C, int size) {
|
||||
for (int i = 0; i < size; ++i) {
|
||||
C[i] = A[i] + B[i];
|
||||
}
|
||||
}
|
||||
|
||||
// NEON 优化向量加法函数
|
||||
void vector_add_optimized(float* A, float* B, float* C, int size) {
|
||||
for (int i = 0; i <= size - 4; i += 4) { // 确保不会越界
|
||||
float32x4_t vecA = vld1q_f32(&A[i]);
|
||||
float32x4_t vecB = vld1q_f32(&B[i]);
|
||||
float32x4_t vecC = vaddq_f32(vecA, vecB);
|
||||
vst1q_f32(&C[i], vecC);
|
||||
}
|
||||
|
||||
// 处理剩余元素(如果 size 不是 4 的倍数)
|
||||
for (int i = size & ~3; i < size; ++i) { // 使用位操作确保从最近的4的倍数开始
|
||||
C[i] = A[i] + B[i];
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
// 检查是否支持NEON
|
||||
#if !defined(__ARM_NEON)
|
||||
printf("Error: This compiler does not support ARM NEON.\n");
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
// 定义并初始化对齐的向量
|
||||
float *A = (float *)aligned_alloc(ALIGNMENT, SIZE * sizeof(float));
|
||||
float *B = (float *)aligned_alloc(ALIGNMENT, SIZE * sizeof(float));
|
||||
float *C = (float *)aligned_alloc(ALIGNMENT, SIZE * sizeof(float));
|
||||
float *C_optimized = (float *)aligned_alloc(ALIGNMENT, SIZE * sizeof(float));
|
||||
|
||||
if (!A || !B || !C || !C_optimized) {
|
||||
printf("Memory allocation failed.\n");
|
||||
free(A); free(B); free(C); free(C_optimized);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// 初始化随机数种子
|
||||
srand(time(0));
|
||||
|
||||
// 初始化向量 A 和 B
|
||||
for (int i = 0; i < SIZE; ++i) {
|
||||
A[i] = rand() % 100; // 生成 0 到 99 的随机数
|
||||
B[i] = rand() % 100;
|
||||
}
|
||||
|
||||
// 基础向量加法计时
|
||||
clock_t start = clock();
|
||||
vector_add(A, B, C, SIZE); // 执行基础向量加法
|
||||
clock_t end = clock();
|
||||
printf("基础向量加法运行时间: %.6f 秒\n", (double)(end - start) / CLOCKS_PER_SEC);
|
||||
|
||||
// NEON 优化向量加法计时
|
||||
start = clock();
|
||||
vector_add_optimized(A, B, C_optimized, SIZE); // 执行 NEON 优化向量加法
|
||||
end = clock();
|
||||
printf("NEON 优化向量加法运行时间: %.6f 秒\n", (double)(end - start) / CLOCKS_PER_SEC);
|
||||
|
||||
// 验证结果
|
||||
for (int i = 0; i < SIZE; ++i) {
|
||||
if (C[i] != C_optimized[i]) {
|
||||
printf("Results do not match at index %d: %f vs %f\n", i, C[i], C_optimized[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 释放内存
|
||||
free(A); free(B); free(C); free(C_optimized);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Loading…
Reference in new issue