首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么gcc的输出比的(对于这段代码)慢得多?

为什么gcc的输出比的(对于这段代码)慢得多?
EN

Stack Overflow用户
提问于 2017-08-05 20:09:19
回答 1查看 1.1K关注 0票数 0

当我在一个定期更新的Ubuntu16.04 64位上编译下面的代码时,使用gcc

代码语言:javascript
复制
gcc source.c -O3 --fast-math

可执行文件需要大约45秒的CPU时间来运行。但是在同一台机器上,在Windows 7 64位上,在发布模式下使用Visual 2012,运行CPU时间不到10秒。造成这种差异的主要原因是什么?gcc的优化方案还不够多吗?Visual的编译器是更好的吗?还是别的什么?

代码语言:javascript
复制
#include <stdio.h>
#include <math.h>
#include <time.h>

#define Nx 1000

int main()
{
    double d = 0.015e-2;        // meter
    double V0 = 400;            // volt
    double De = 1800e-4;        // m^2 per sec
    double mu_e = 2.9e1 / 760;  // m^2 per volt sec
    double n0 = 1e19;           // per m^3
    double e_eps = 1.602e-19 / 8.854e-12;
    double ne[Nx], je[Nx], E[Nx];
    double dx = d / (Nx - 1);
    double dt = 1e-14;          // s
    const int Nt = 500000;
    int i, k;
    double sum;
    FILE *fp_ne, *fp_E;
    double alpha, exp_alpha, R;
    int ESign = -1;
    clock_t start_t, end_t;

    start_t = clock();
    // initialization
    for (i = 1; i < Nx; i++)
        ne[i] = n0;
    ne[0] = 1e-4 * n0;

    for (i = 0; i < Nx; i++)
        E[i] = -V0 / d;

    // time loop
    for (k = 0; k < Nt; k++)
    {
        if (k%1000==0) printf("k = %d\n", k);
        for (i = 0; i < (Nx-1); i++)
        {
            alpha = mu_e*dx*E[i]/De;
            exp_alpha = exp(alpha);
            R = (exp_alpha-1)/alpha;
            je[i] = (De/(dx*R))*(ne[i]-exp_alpha*ne[i+1]);
        }

        for (i = 1; i < (Nx - 1); i++)
            ne[i] += -dt/dx*(je[i] - je[i-1]);
        ne[Nx - 1] = ne[Nx - 2];

        sum = 0;
        for (i = 0; i < (Nx - 1); i++)
            sum += dx*je[i];
        for (i = 0; i < (Nx - 1); i++)
        {
            E[i] += -dt*e_eps*(sum / d - je[i]);
            if (E[i]>=0) ESign=+1;
        }
        if (ESign==1) break;
    }

    // output
    printf("time=%e\n",k*dt);
    fp_ne = fopen("ne.txt", "w");
    fp_E = fopen("E.txt", "w");
    fprintf(fp_ne, "# x (cm)\tne(per cm^3)\n");
    fprintf(fp_E,  "# x (cm)\tE(V/cm)\n");
    for (i = 0; i < Nx; i++)
        fprintf(fp_ne, "%f\t%e\n", i*dx*100,ne[i]/1e6);
    for (i = 0; i < Nx-1; i++)
        fprintf(fp_E, "%f\t%e\n", i*dx*100, fabs(E[i])/1e2);
    fclose(fp_ne);
    fclose(fp_E);
    end_t = clock();
    printf("CPU time = %f\n", (double)(end_t - start_t) / CLOCKS_PER_SEC);
}
EN

回答 1

Stack Overflow用户

发布于 2017-08-05 21:33:54

我做的第一件事就是注释掉循环中的I/O。

代码语言:javascript
复制
//if (k%1000==0) printf("k = %d\n", k);

我得到了以下的时间,只有那个变化。最后的fprintf调用确实会对时间产生显著的影响,但不会影响到它们之间的相对差异,所以我不打算再测量所有这些。

我在我的i5 (所有这些都是用标准-O2编译的)上得到了这些时间:

  • GCC 7.1: CPU时间= 23.459520
  • Clang 4.0.1: CPU时间= 22.936315
  • 英特尔17.0.4: CPU时间= 7.830828

在同一台机器上的Windows 10的Qemu/libvirt虚拟机上,我得到了以下时间:

  • MinGW-w64 GCC 6.3: CPU时间= 76.122000
  • 对2015.3: CPU时间= 13.497000
  • VS 2017: CPU时间= 49.306000

在should上(本地Linux,但Win32 API仿真,仍然可以与本地Linux代码执行相媲美)。

  • MinGW-w64 GCC 6.3: CPU时间= 56.074000
  • 对2015.3: CPU时间= 12.048000
  • VS 2017: CPU时间= 34.541000

长话短说:这些输出似乎是解决这个特殊问题的最佳代码:

  1. Linux上的Intel (可能也在Windows上)
  2. VS 2015.3
  3. Linux上的GCC/Clang
  4. VS 2017
  5. GCC。

查看组装将是唯一的办法,以了解这一点,但正确的分析,这是超出我的能力。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45525971

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档