You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言2048阶矩阵乘法计时及const数组随机初始化问题

2048×2048矩阵乘法耗时测算实现方案

核心问题修复逻辑

两个问题可按规则解决,不需要修改现有matrixMult函数和gettimeofday计时框架的接口:

  • 全局const指针无有效内存:const float*类型的指针仅限制指向的内容不可修改,指针本身的指向可以变更,禁止直接在栈上分配大矩阵(单矩阵占16MB,栈空间默认通常仅8MB会直接溢出),统一在堆上申请内存。
  • const数组随机初始化:不要直接对const指向的内存做写入操作(会触发编译错误+未定义行为),申请内存时先用可写的临时浮点指针操作,完成随机值填充后再把地址赋值给const类型的A、B指针,完全符合const语义要求。

完整实现步骤

1. 基础定义与内存分配

先统一宏定义矩阵维度,避免魔法数,再完成三个矩阵的堆内存申请与合法性校验:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <time.h>

#define MAT_DIM 2048
#define TOTAL_ELEM (MAT_DIM * MAT_DIM)

// 全局指针声明,和现有框架保持一致
const float *A, *B;
float *C;

// 外部传入的矩阵乘法函数,签名匹配通用实现
extern void matrixMult(const float* A, const float* B, float* C, int n);

内存分配逻辑放在程序初始化阶段(main函数开头即可):

// 用可写临时指针申请A、B的内存,用于后续初始化
float* tmp_A = (float*)malloc(sizeof(float) * TOTAL_ELEM);
float* tmp_B = (float*)malloc(sizeof(float) * TOTAL_ELEM);
C = (float*)malloc(sizeof(float) * TOTAL_ELEM);

if (!tmp_A || !tmp_B || !C) {
    perror("memory alloc failed");
    exit(EXIT_FAILURE);
}

2. 随机值初始化

随机种子仅初始化1次即可,填充[0,1)范围的浮点值,避免数值过大导致乘法结果溢出float精度范围:

srand((unsigned int)time(NULL));
for (int i = 0; i < TOTAL_ELEM; i++) {
    tmp_A[i] = (float)rand() / (float)(RAND_MAX + 1.0f);
    tmp_B[i] = (float)rand() / (float)(RAND_MAX + 1.0f);
}

// 初始化完成后,将内存地址挂载到const全局指针,后续不可通过A、B修改矩阵内容
A = tmp_A;
B = tmp_B;

3. 10组计时样本采集

基于现有gettimeofday框架实现,每次计时前清空输出矩阵C的残留值,避免干扰计算逻辑:

// 时间差计算工具函数,返回单位:毫秒
static double get_elapsed_ms(struct timeval start, struct timeval end) {
    return (end.tv_sec - start.tv_sec) * 1000.0 + (end.tv_usec - start.tv_usec) / 1000.0;
}

int main() {
    // 此处放前面的内存分配、初始化逻辑

    // 可选:预跑1次矩阵乘法,加载CPU/指令缓存,避免第一组冷启动数据偏差
    memset(C, 0, sizeof(float) * TOTAL_ELEM);
    matrixMult(A, B, C, MAT_DIM);

    const int sample_num = 10;
    double total_cost = 0.0;
    for (int s = 0; s < sample_num; s++) {
        memset(C, 0, sizeof(float) * TOTAL_ELEM);
        struct timeval t_start, t_end;
        gettimeofday(&t_start, NULL);
        matrixMult(A, B, C, MAT_DIM);
        gettimeofday(&t_end, NULL);

        double cost = get_elapsed_ms(t_start, t_end);
        printf("Sample %d cost: %.2f ms\n", s+1, cost);
        total_cost += cost;
    }
    printf("Average cost of 10 samples: %.2f ms\n", total_cost / sample_num);

    // 退出前释放内存
    free((void*)A);
    free((void*)B);
    free(C);
    return 0;
}

关键注意事项

  • 编译时必须开启-O2或更高等级优化,debug模式(-O0)下的矩阵乘法耗时没有性能参考价值。
  • 不要强制转换const指针直接写入内容,比如*(float*)A = xxx,属于C标准定义的未定义行为,可能触发运行时段错误。
  • 如果需要更精准的计时,可以在测试时关闭CPU睿频、固定CPU频率,避免频率波动导致样本数据离散度过大。
  • 不需要每次采集样本都重新初始化A、B矩阵,重复填充随机值会引入额外耗时,干扰计时结果。

内容的提问来源于stack exchange,提问作者mitousis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.02 03:12:33