diff --git a/mian.c b/mian.c new file mode 100644 index 0000000..1934267 --- /dev/null +++ b/mian.c @@ -0,0 +1,158 @@ +#include +#include +#include +#include "ctime.h" + +int main() { + // 为向量a分配内存空间,大小为VECTOR_SIZE个float类型元素所占的空间 + float* a = (float*)malloc(VECTOR_SIZE * sizeof(float)); + // 为向量b分配内存空间,大小为VECTOR_SIZE个float类型元素所占的空间 + float* b = (float*)malloc(VECTOR_SIZE * sizeof(float)); + // 为基础向量加法结果向量分配内存空间,大小为VECTOR_SIZE个float类型元素所占的空间 + float* resultVectorBase = (float*)malloc(VECTOR_SIZE * sizeof(float)); + // 为NEON优化向量加法结果向量分配内存空间,大小为VECTOR_SIZE个float类型元素所占的空间 + float* resultVectorNeon = (float*)malloc(VECTOR_SIZE * sizeof(float)); + + // 为矩阵A分配内存空间,大小为MATRIX_SIZE * MATRIX_SIZE个float类型元素所占的空间 + float* A = (float*)malloc(MATRIX_SIZE * MATRIX_SIZE * sizeof(float)); + // 为矩阵B分配内存空间,大小为MATRIX_SIZE * MATRIX_SIZE个float类型元素所占的空间 + float* B = (float*)malloc(MATRIX_SIZE * MATRIX_SIZE * sizeof(float)); + // 为基础矩阵乘法结果矩阵分配内存空间,大小为MATRIX_SIZE * MATRIX_SIZE个float类型元素所占的空间 + float* resultMatrixBase = (float*)malloc(MATRIX_SIZE * MATRIX_SIZE * sizeof(float)); + // 为NEON优化矩阵乘法结果矩阵分配内存空间,大小为MATRIX_SIZE * MATRIX_SIZE个float类型元素所占的空间 + float* resultMatrixNeon = (float*)malloc(MATRIX_SIZE * MATRIX_SIZE * sizeof(float)); + + // 初始化向量a和b的元素值 + // 循环遍历向量的每个元素 + for (int i = 0; i < VECTOR_SIZE; ++i) { + // 将向量a的第i个元素赋值为i的浮点数形式 + a[i] = (float)i; + // 将向量b的第i个元素赋值为i + 1的浮点数形式 + b[i] = (float)(i + 1); + } + + // 初始化矩阵A和B的元素值 + // 循环遍历矩阵的每个元素 + for (int i = 0; i < MATRIX_SIZE * MATRIX_SIZE; ++i) { + // 将矩阵A的第i个元素赋值为i的浮点数形式 + A[i] = (float)i; + // 将矩阵B的第i个元素赋值为i + 1的浮点数形式 + B[i] = (float)(i + 1); + } + +#ifdef _WIN32 + // 在Windows平台下,定义用于存储时钟频率的LARGE_INTEGER结构体变量frequency + LARGE_INTEGER frequency; + // 获取高精度性能计数器的频率,将结果存储到frequency变量中 + QueryPerformanceFrequency(&frequency); + // 定义用于存储起始时间和结束时间的LARGE_INTEGER结构体变量startTime和endTime + LARGE_INTEGER startTime, endTime; +#else + // 在非Windows平台下,定义用于存储时间的timespec结构体变量start和end + struct timespec start, end; +#endif + + // 向量加法基础实现的时间测量及结果输出 + + // 向量加法基础实现(Windows平台部分) +#ifdef _WIN32 + // 获取高精度性能计数器的当前值作为起始时间,存储到startTime变量中 + QueryPerformanceCounter(&startTime); + // 调用基础向量加法函数,对向量a和b进行加法运算,结果存储到resultVectorBase中 + vectorAddBase(a, b, resultVectorBase, VECTOR_SIZE); + // 获取高精度性能计数器的当前值作为结束时间,存储到endTime变量中 + QueryPerformanceCounter(&endTime); + // 调用函数计算并输出Windows平台下基础向量加法的执行时间 + printf("Base vector addition time: %f seconds\n", get_time_diff_windows(startTime, endTime, frequency)); +#else + // 获取单调时钟的当前时间作为起始时间,存储到start变量中 + clock_gettime(CLOCK_MONOTONIC, &start); + // 调用基础向量加法函数,对向量a和b进行加法运算,结果存储到resultVectorBase中 + vectorAddBase(a, b, resultVectorBase, VECTOR_SIZE); + // 获取单调时钟的当前时间作为结束时间,存储到end变量中 + clock_gettime(CLOCK_MONOTONIC, &end); + // 调用函数计算并输出非Windows平台下基础向量加法的执行时间 + printf("Base vector addition time: %f seconds\n", get_time_diff(start, end)); +#endif + + // 向量加法NEON优化实现的时间测量及结果输出 + + // 向量加法NEON优化实现(Windows平台部分) +#ifdef _WIN32 + // 获取高精度性能计数器的当前值作为起始时间,存储到startTime变量中 + QueryPerformanceCounter(&startTime); + // 调用NEON优化向量加法函数,对向量a和b进行加法运算,结果存储到resultVectorNeon中 + vectorAddNeon(a, b, resultVectorNeon, VECTOR_SIZE); + // 获取高精度性能计数器的当前值作为结束时间,存储到endTime变量中 + QueryPerformanceCounter(&endTime); + // 调用函数计算并输出Windows平台下NEON优化向量加法的执行时间 + printf("NEON optimized vector addition time: %f seconds\n", get_time_diff_windows(startTime, endTime, frequency)); +#else + // 获取单调时钟的当前时间作为起始时间,存储到start变量中 + clock_gettime(CLOCK_MONOTONIC, &start); + // 调用NEON优化向量加法函数,对向量a和b进行加法运算,结果存储到resultVectorNeon中 + vectorAddNeon(a, b, resultVectorNeon, VECTOR_SIZE); + // 获取单调时钟的当前时间作为结束时间,存储到end变量中 + clock_gettime(CLOCK_MONOTONIC, &end); + // 调用函数计算并输出非Windows平台下NEON优化向量加法的执行时间 + printf("NEON optimized vector addition time: %f seconds\n", get_time_diff(start, end)); +#endif + + // 矩阵乘法基础实现的时间测量及结果输出 + + // 矩阵乘法基础实现(Windows平台部分) +#ifdef _WIN32 + // 获取高精度性能计数器的当前值作为起始时间,存储到startTime变量中 + QueryPerformanceCounter(&startTime); + // 调用基础矩阵乘法函数,对矩阵A和B进行乘法运算,结果存储到resultMatrixBase中 + matrixMultiplyBase(A, B, resultMatrixBase, MATRIX_SIZE); + // 获取高精度性能计数器的当前值作为结束时间,存储到endTime变量中 + QueryPerformanceCounter(&endTime); + // 调用函数计算并输出Windows平台下基础矩阵乘法的执行时间 + printf("Base matrix multiplication time: %f seconds\n", get_time_diff_windows(startTime, endTime, frequency)); +#else + // 获取单调时钟的当前时间作为起始时间,存储到start变量中 + clock_gettime(CLOCK_MONOTONIC, &start); + // 调用基础矩阵乘法函数,对矩阵A和B进行乘法运算,在矩阵乘法运算中,按照常规算法计算矩阵A和B的乘积,结果存储到resultMatrixBase中 + matrixMultiplyBase(A, B, resultMatrixBase, MATRIX_SIZE); + // 获取单调时钟的当前时间作为结束时间,存储到end变量中 + clock_gettime(CLOCK_MONOTONIC, &end); + // 调用函数计算并输出非Windows平台下基础矩阵乘法的执行时间 + printf("Base matrix multiplication time: %f seconds\n", get_time_diff(start, end)); +#endif + + // 矩阵乘法NEON优化实现的时间测量及结果输出 + + // 矩阵乘法NEON优化实现(Windows平台部分) +#ifdef _WIN32 + // 获取高精度性能计数器的当前值作为起始时间,存储到startTime变量中 + QueryPerformanceCounter(&startTime); + // 调用NEON优化矩阵乘法函数,对矩阵A和B进行乘法运算,结果存储到resultMatrixNeon中 + matrixMultiplyNeon(A, B, resultMatrixNeon, MATRIX_SIZE); + // 获取高精度性能计数器的当前值作为结束时间,存储到endTime变量中 + QueryPerformanceCounter(&endTime); + // 调用函数计算并输出Windows平台下NEON优化矩阵乘法的执行时间 + printf("NEON optimized matrix multiplication time: %f seconds\n", get_time_diff_windows(startTime, endTime, frequency)); +#else + // 获取单调时钟的当前时间作为起始时间,存储到start变量中 + clock_gettime(CLOCK_MONOTONIC, &start); + // 调用NEON优化矩阵乘法函数,对矩阵A和B进行乘法运算,结果存储到resultMatrixNeon中 + matrixMultiplyNeon(A, B, resultMatrixNeon, MATRIX_SIZE); + // 获取单调时钟的当前时间作为结束时间,存储到end变量中 + clock_gettime(CLOCK_MONOTONIC, &end); + // 调用函数计算并输出非Windows平台下NEON优化矩阵乘法的执行时间 + printf("NEON optimized matrix multiplication time: %f seconds\n", get_time_diff(start, end)); +#endif + + // 释放之前为向量和矩阵分配的内存空间,以避免内存泄漏 + free(a); + free(b); + free(resultVectorBase); + free(resultVectorNeon); + free(A); + free(B); + free(resultMatrixBase); + free(resultMatrixNeon); + + return 0; +} \ No newline at end of file