用于数值模拟的C与C++(性能)

Wuh*_*tzu 6 c c++ simulation performance numeric

我即将编写一个非晶格扩散限制聚合(DLA)模拟,我想知道是否使用C或C++.

出于设计原因,C++会很好,但我想知道C会表现得更好.当然我了解算法性能并选择了最好的算法.所以我不是在谈论将O(n ^ 2)改为O(log n)或类似的.我试图减少我的常数.

如果您不了解DLA,它基本上归结为具有一系列双精度(大小在10 ^ 3和10 ^ 6之间)并且在循环中选择随机双精度来比较(大于/小于)阵列的大部分.

因此,对此重要的性能差异是数据访问和调用功能:

  • 数据访问:具有公共数据成员的C struct与C++类与具有私有数据成员和访问者的C++类.
  • 调用函数:C函数与C++成员函数.

我是否正确地得出结论,判断这一点的最终方法是查看汇编代码(例如比较移动/加载,跳转和调用的数量)?这当然是编译器相关的(例如,您可以将糟糕的C编译器与优秀的C++编译器进行比较).我正在使用Gnu编译器(gcc和g ++).

我发现通过gcc和g ++生成的程序集在跳转次数(无),移动/加载以及对以下两个程序的调用方面几乎相同:

C程序

#include <stdlib.h>

typedef struct 
{
    double x;
} particle;

double square(double a)
{
    return a*a;
}

int main()
{

    particle* particles = malloc(10*sizeof(particle));
    double res;

    particles[0].x = 60.42;

    res = square(particles[0].x);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

C++程序

class particle
{
    public:
        double x;

    public:
        double square()
        {
            return x*x;
        }

};

int main()
{

    particle* particles = new particle[10];
    double res;

    particles[0].x = 60.42;

    res = particles[0].square();

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

如果我在C++程序中使用私有成员数据,当我调用粒子[0] .setx(60.42)时,我当然会在程序集中再次调用.

这是否意味着我不妨选择C++作为C,因为它们产生几乎相同的汇编代码?我应该避免私有成员数据,因为它增加了额外的函数调用(例如,在程序集中调用昂贵)?

Jer*_*fin 10

考虑到你所概述的事物类型,我会惊讶地看到C对其中任何一个都有显着的优势.根据你所说的,我还猜测你所做的比较是基于很少或没有启用优化的编译.启用完全优化后,我甚至会发现那些消失了.

从长远来看,C++提供了更多的优化机会.矩阵运算相当普遍(虽然我不确定它是否适用于您的DLA仿真)是表达式模板,您可以使用它来"展平"计算以避免复制本来必要的数据.

底线:更糟糕的是,C++最终会完全等同于C(即,在最糟糕的情况下,您编写的C++代码几乎与C代码相同,并且在性能上没有差别).最好的情况是,C++的额外功能(特别是模板)为您提供了以C或者不可能或非常不切实际的方式进行优化的机会.