2

为了堆叠溢出成员,我正在编写一个模拟器,它需要多个循环(有时超过 1,000,000 个),每个循环都涉及大量计算。因此,在循环上节省 10 毫秒可以节省超过 160 分钟的额外计算时间。所以我正在为我能得到的每一个代码优化而奋斗。以前我已经将我所有的系统参数从一个文件导入到向量中。过了一会儿,我意识到:

  1. 调用常量 int/double/... 比调用常规 int/double/... 更快
  2. 使用数组比使用向量更快
  3. 我不需要 std::string 的全部功能,可以制作一个简单的仿冒版本来使用

最初我天真地以为我可以转换std::vector<double>std::vector<const double>. 由于我也一直在尝试使用 linux 制作这个跨平台,我发现 Visual Studio Express 编译器忽略了不能像那样声明 const 的事实(而 linux 只会抛出大量错误)。

我决定在初始化的结构中使用常量数组;但是,无法弄清楚如何正确初始化它。(我遇到的大多数/所有帮助论坛都说将其声明static const int*并初始化为全局,我认为这不适用于我需要的东西)。我终于开发了这个最终解决方案;但是,我相信我犯了一个“禁忌”,因为我最终使用指针来声明常量。它编译并运行没有错误,因此我想知道,使用指针初始化常量数组是错误的吗?如果是这样,你还会怎么做?(我知道以这种方式获取所有数据可能会更慢,但在时间很重要的部分,它应该更快地调用......我认为)

#include <stdio.h>
#include <malloc.h>
#include <conio.h>

#if defined(_WIN32) || defined(_WIN64)
#define gsize _msize
#else
#define gsize malloc_usable_size
#endif

struct testy{
    const int *i;
    const double *d;
    testy(){
        i=(const int *)malloc(0);
        d=(const double *)malloc(0);
    }
};

inline const int* getDat(const int* dst, int* src){
    dst=(const int*)realloc((void *)dst,gsize((void *)src)); // Allocate enough memory to hold the data
    return src;
}

inline const double* getDat(const double* dst, double* src){
    dst=(const double*)realloc((void *)dst,gsize((void *)src)); // Allocate enough memory to hold the data
    return src;
}

int main(){
    testy data;
    int *tmp_i = (int *)malloc(0);
    double *tmp_d = (double *)malloc(0);

    for(int i=0;i<3;i++){ // load empty array with what i want
        tmp_i=(int*)realloc((void *)tmp_i,gsize((void *)tmp_i)+1*sizeof(int)); // Increase size by one
        tmp_i[i]=i;
    }
    for(int i=0;i<3;i++){ // load empty array with what i want
        tmp_d=(double*)realloc((void *)tmp_d,gsize((void *)tmp_d)+1*sizeof(double)); // Increase size by one
        tmp_d[i]=i;
    }

    data.i=getDat(data.i,tmp_i);
    data.d=getDat(data.d,tmp_d);

    printf("\nIntegers\n");
    for(int i=0;i<(gsize((void *)data.i)/sizeof(int));i++)
        printf("%d\t",data.i[i]);

    printf("\nDoubles\n");
    for(int i=0;i<(gsize((void *)data.d)/sizeof(double));i++)
        printf("%lg\t",data.d[i]);

    free(tmp_i); free(tmp_d);
    _getch();
    return 0;
}

我从这段代码中删除了仿冒字符串及其用途,因为在声明它的数组时存在一些问题,我不想在这里问多个问题。

4

1 回答 1

3
  1. 删除realloc. 这很昂贵,而且还会碎片化内存
  2. const不会有任何区别-您必须在一天结束时访问内存,而该const位只是确保您不会更改不应该更改的内容
  3. (gsize((void *)data.d)/sizeof(double)如果值是不可变的,则将之类的东西放在 for 循环之外。防止每次循环调用函数
  4. 使内存缓存工作。即按顺序访问内存中的内容。从内存传送到处理器的数据可以很容易地预取。
  5. 至于做任何复杂的操作(你没有显示)使用一点代数来简化方程。如果可能的话,使用整数而不是双精度数,这取决于问题空间。
于 2013-07-24T02:02:21.783 回答