首页 > 解决方案 > Best way to optimize performance of program with arrays that regularly need to be reset to zero in C?

问题描述

I have searched to see if this question has been asked before, but I could not find anything - but when I was searching I found some many interesting points about optimization in this answer and the other answers to a question about optimization.

My question is to ask which way is the most efficient/ fastest to set the elements of a large array to zero using C.

The program will track a large number of particles, >>>1000. Each particle is described by several variables some of which will need to be reset to zero every time around a loop, which will be executed >>>1000 times. The exact number of particles that can be handled will depend on the efficiency of the code.

The choices seem to be the following and I have ordered them as I guess from least efficient to most efficient. (I try to describe them with indicative code fragments - no way, of course, is this code that can run, but just something to indicate the strategy - and I realise that loop unrolling might be a good idea, but for simplicity it is not included below)

  1. N particles are represented by an array of a structure that contains all the information about each particle so
  /*structure definition*/
struct particle {
  double a;
  double b;
  ....
};

  /*memory allocation*/
struct particle * part; 
part = (struct particle *)calloc(N,sizeof(particle));

  /*routine to set some particle variables to zero*/
for (i=0;i<N;i++)
{
  part[i].a=0;
  part[i].b=0;
  .... etc....
}
  1. N particles are represented by several arrays in a structure that contains all the information about the ensemble of particles so
  /*structure definition*/
struct ensemble {
  double * a;
  double * b;
  ....
};

  /*memory allocation*/
struct ensemble group; 
group.a = (double *)calloc(N,sizeof(double));
group.b = (double *)calloc(N,sizeof(double));

  /*routine to set some particle variables to zero*/
for (i=0;i<N;i++)
{
  group.a[i]=0;
  group.b[i]=0;
  .... etc....
}
  1. exactly the same as 2) above but the variables are reset to zero with
  /*routine to set some particle variables to zero*/
free(group.a); group.a = (double *)calloc(N,sizeof(double));
free(group.b); group.b = (double *)calloc(N,sizeof(double));
  1. instinctively I think there must be an easier way to than 3) to write 0 to memory, which does not require freeing and then reallocating large amounts of memory every time around the loop. -- The answers to this question mention memset, which i am guessing would work, provided that setting everything to zero bytewise will give doubles with values of 0.0000000e00.

  2. same as 2), 3), 4) above, but instead of using any data structure just grab memory for separate arrays.

  /*memory allocation*/
double * a, * b, ... ; 
a = (double *)calloc(N,sizeof(double));
b = (double *)calloc(N,sizeof(double));

  /*routine to set some particle variables to zero*/
for (i=0;i<N;i++)
{
  a[i]=0;
  b[i]=0;
  .... etc....
}

Finally, I saw something that *(a+i)=0 would be quicker than a[i]=0, but for readability the code above has a[i] array indexing.

I also guess that it may be the compiler with optimization flags turned on will do some of these things.

I would be really interested to hear what would be expected to be fastest and how much improvement might be obtained in each refinement..

标签: arrayscperformancememory

解决方案


推荐阅读