使用calloc'ed vs明确归零内存的时间

时间:2014-08-10 10:25:56

标签: c performance

下面的示例在一个简单但不完全是微不足道的内存结构中调用了一些内存。然后它将显式设置为零或不设置,由EXPLICIT_RESET控制为1或0.然后将这些值相加。总和总是如预期的那样为零。

有趣的是时机。代码看起来比实际更长,因为#ifdefs可以在Cygwin上使用Microsoft的CL编译器v17.00和gcc 4.8.3进行计时。

cl /O2 /DEXPLICIT_RESET=0 test.c /Fetest.exe
./test.exe

我系统上的典型定时值为20000-25000。

cl /O2 /DEXPLICIT_RESET=1 test.c /Fetest.exe
./test.exe

典型时间值2500-3000。

gcc -O3 -DEXPLICIT_RESET=0 test.c -o test
./test.exe

典型定时值8000-10000。 (这些不具有可比性,因为我跳过了应该应用Win32代码的缩放因子。)

gcc -O3 -DEXPLICIT_RESET=1 test.c -o test
./test.exe

典型的定时值1000。

您可以进一步简化数据结构,但它们已经接近仍然会引发所述行为的限制。

我可以在没有显式初始化的情况下获得快速访问吗?

在我的真实程序中,显式重置内存需要很长时间,所以我想依赖calloc。但是我当然希望访问的内存很快。所以目前我陷入了困境:要么在calloc之上进行缓慢的初始化,要么缓慢访问。

#include <stdio.h>
#include <stdlib.h>

#ifdef _WIN32
  #include <windows.h>
  #include <time.h>
  LARGE_INTEGER tu0, tu1;
#else
  #include <sys/time.h>
  struct timeval tu0, tu1;
#endif

struct dataType
{
  int dummy1[4];
  int dummy2;
};

struct blockType
{
  int value;
  struct dataType list[16];
};

struct pageType
{
  struct blockType * list;
};


#define BLOCKS_PER_PAGE 100000

int main(int argc, char * argv[])
{
  int timing, j, sum = 0;

  struct pageType * pagep = (struct pageType *)
    calloc(1, sizeof(struct pageType));

  pagep->list = (struct blockType *)
    calloc(BLOCKS_PER_PAGE, sizeof(struct blockType));

#if EXPLICIT_RESET
  for (j = 0; j < BLOCKS_PER_PAGE; j++)
    pagep->list[j].value = 0;
#endif

#ifdef _WIN32
  QueryPerformanceCounter(&tu0);
#else
  gettimeofday(&tu0, NULL);
#endif

  for (j = 0; j < BLOCKS_PER_PAGE; j++)
    sum += pagep->list[j].value;

#ifdef _WIN32
  QueryPerformanceCounter(&tu1);
  timing = tu1.QuadPart - tu0.QuadPart;
#else
  gettimeofday(&tu1, NULL);
  timing = 1000000 * (tu1.tv_sec  - tu0.tv_sec )
         +           (tu1.tv_usec - tu0.tv_usec);
#endif

  printf("sum is %d, timing is %d\n", sum, timing);
  exit(0);
}

0 个答案:

没有答案