代码之家  ›  专栏  ›  技术社区  ›  Martin

C中哪个更快?在堆栈上多次分配固定大小的数组,还是在堆上分配一次并多次访问它?

  •  2
  • Martin  · 技术社区  · 2 年前

    在第一种方法中,我在堆上分配一个数组“k”,将其传递给RK4步长函数,然后进行计算。您可以看到以下相关功能:

    void rk4Step(double t, double dt, double* p, double* y, double* k, int n_eqns, ODE* f) {
        double y_orig_val;
        for (int i = 0; i < n_eqns; i++) {
            y_orig_val = y[i];
            k[0] = dt * (*f)(p, t, y, i);
    
            y[i] += 0.5 * k[0];
            k[1] = dt * (*f)(p, t + 0.5 * dt, y, i);
            y[i] = y_orig_val;
    
            y[i] += 0.5 * k[1];
            k[2] = dt * (*f)(p, t + 0.5 * dt, y, i);
            y[i] = y_orig_val;
    
            y[i] += k[2];
            k[3] = dt * (*f)(p, t + dt, y, i);
            y[i] = y_orig_val;
    
            y[i] += 1.0 / 3.0 * (1.0 / 2.0 * (k[0] + k[3]) + (k[1] + k[2]));
        }
    }
    
    void solveODE(double t, double dt, int n_eqns, int n_params, int n_steps, ODE* f) {
    
        double* y = malloc(n_eqns * sizeof(double));
        double* p = malloc(n_params * sizeof(double));
        double* k = malloc(4 * sizeof(double));
        init(p, y, n_eqns);
    
        FILE* sol = fopen("sol.dat", "w");
    
        for (int i = 0; i <= n_steps; i++) {
            fprintf(sol, "%f\t", t);
            for (int j = 0; j < n_eqns-1; j++) {
                fprintf(sol, "%f\t", y[j]);
            }
            fprintf(sol, "%f\n", y[n_eqns-1]);
    
            rk4Step(t, dt, p, y, k, n_eqns, f);
            t += dt;
        }
    
        free(y);
        free(p);
        free(k);
        fclose(sol);
    }
    

    在另一种方法中,变量“k”不是在堆上分配的,而是在rk4Step函数体的堆栈上分配的。如您所见,rk4Step函数用于循环中。这就是变量k将在每次迭代中一次又一次地分配到堆栈上。

    我知道在堆栈上处理变量要快得多,但在这种情况下也是这样吗?

    1 回复  |  直到 2 年前
        1
  •  1
  •   infinitezero    2 年前

    无需在堆上分配:

    void solveODE(double t, double dt, int n_eqns, int n_params, int n_steps, ODE* f) {
    
        double y[n_eqns];
        double p[n_params];
        double k[4];
        init(p, y, n_eqns);
    
        FILE* sol = fopen("sol.dat", "w");
    
        for (int i = 0; i <= n_steps; i++) {
            fprintf(sol, "%f\t", t);
            for (int j = 0; j < n_eqns-1; j++) {
                fprintf(sol, "%f\t", y[j]);
            }
            fprintf(sol, "%f\n", y[n_eqns-1]);
    
            rk4Step(t, dt, &p, &y, &k, n_eqns, f);
            t += dt;
        }
    
     
        fclose(sol);
    }