Re: remove BufferBlockPointers for speed and space - Mailing list pgsql-patches

From Qingqing Zhou
Subject Re: remove BufferBlockPointers for speed and space
Date
Msg-id ddh56r$bk0$1@news.hub.org
Whole thread Raw
In response to remove BufferBlockPointers for speed and space  ("Qingqing Zhou" <zhouqq@cs.toronto.edu>)
Responses Re: remove BufferBlockPointers for speed and space  (Tom Lane <tgl@sss.pgh.pa.us>)
List pgsql-patches
"Tom Lane" <tgl@sss.pgh.pa.us> writes:
>
> This is definitely going to tell us a lot more about the compiler's loop
> strength reduction algorithms than it is going to tell about the time to
> evaluate any one of these expressions in isolation.  What's worse, the
> compiler would be quite within its rights to detect that k isn't used
> anywhere, and optimize the loop away completely.
>

Yes, it is possible. A safter way is to examine the assembling code. And I
found there is no such optimization in Linux/gcc3.2.

> What I would suggest is first to fill another array with some large
> number of buffer numbers (randomly chosen from 1..N) and then time loops
> of the form
>
> for (i = 0; i < arraysize; i++)
> {
> bn = buffernumbers[i];
> bufferlocs[i] = BufferGetBlock(bn);
> }
>
> for all three possible definitions of BufferGetBlock (where both arrays
> are global variables, just to be sure the compiler doesn't think it can
> discard the store).  This should give some numbers worth trusting.
>

I've patched the code according to your suggestion. Result is:

SunOS/gcc 3.2
verify: 1308873472 :duration round 1 of array method: 8.906 ms
verify: 1308873472 :duration round 2 of array method: 8.775 ms
verify: 1308873472 :duration round 3 of array method: 8.761 ms
verify: 1308873472 :duration round 1 of mul method: 6.454 ms
verify: 1308873472 :duration round 2 of mul method: 6.545 ms
verify: 1308873472 :duration round 3 of mul method: 6.535 ms
verify: 1308873472 :duration round 1 of shift method: 6.534 ms
verify: 1308873472 :duration round 2 of shift method: 6.597 ms
verify: 1308873472 :duration round 3 of shift method: 6.540 ms

Linux/gcc 3.2
verify: -2141277440 :duration round 1 of array method: 2.385 ms
verify: -2141277440 :duration round 2 of array method: 2.116 ms
verify: -2141277440 :duration round 3 of array method: 2.057 ms
verify: -2141277440 :duration round 1 of mul method: 0.943 ms
verify: -2141277440 :duration round 2 of mul method: 0.983 ms
verify: -2141277440 :duration round 3 of mul method: 0.840 ms
verify: -2141277440 :duration round 1 of shift method: 0.864 ms
verify: -2141277440 :duration round 2 of shift method: 0.931 ms
verify: -2141277440 :duration round 3 of shift method: 0.968 ms


The test file is attached:
---
/*
 * buftest.c
 */
#include <stdio.h>
#include <stdlib.h>
#include <sys/file.h>
#include <sys/time.h>
#include <unistd.h>

#define BLCKSZ  8192
#define NBuffers 80000

typedef void* Block;

Block *array = NULL;
Block *reslt = NULL;
int  *bufnm = NULL;

static int grand(int min, int max)
{
    return (min + (int) (max * 1.0 * rand() / (RAND_MAX + 1.0)));
}

int main(void)
{
 int  n, i, round, method;
 Block start;
 struct timeval start_t, stop_t;
 long usecs;

 srandom(getpid());

 array = (Block *) calloc(NBuffers, sizeof(Block));
 reslt = (Block *) calloc(NBuffers, sizeof(Block));
 bufnm = (int   *) calloc(NBuffers, sizeof(int));

 start = (Block)0xff3386;
 for (i = 0; i < NBuffers; i++)
  array[i] = start + BLCKSZ*i;
 for (i = 0; i < NBuffers; i++)
  bufnm[i] = grand(0, NBuffers);

 for (method = 0; method < 3; method ++)
 {
  start = (Block)0xff3386;
  for (round = 0; round < 3; round ++)
  {
   gettimeofday(&start_t, NULL);
   if (method == 0)
   {
    for (i = 0; i < NBuffers; i++)
    {
     n = bufnm[i];
     reslt[i] = array[n];
    }

   }
   if (method == 1)
   {
    for (i = 0; i < NBuffers; i++)
    {
     n = bufnm[i];
     reslt[i] = start + n*BLCKSZ;
    }
   }
   if (method == 2)
   {
    for (i = 0; i < NBuffers; i++)
    {
     n = bufnm[i];
     reslt[i] = start + (n<<13);
    }
   }
   gettimeofday(&stop_t, NULL);

   usecs = 0;
   for (i = 0; i< NBuffers; i++)
    usecs += (long) reslt[i];
   fprintf(stdout, "verify: %ld :", usecs );

   if (stop_t.tv_usec < start_t.tv_usec)
   {
     stop_t.tv_sec--;
     stop_t.tv_usec += 1000000;
   }

   usecs = (long) (stop_t.tv_sec - start_t.tv_sec) * 1000000
     + (long) (stop_t.tv_usec - start_t.tv_usec);

   fprintf (stdout, "duration round %d of %s method: %ld.%03ld ms\n",
       round + 1,
       method==0?"array":method==1?"mul":"shift",
       (long) ((stop_t.tv_sec - start_t.tv_sec) * 1000 +
         (stop_t.tv_usec - start_t.tv_usec) / 1000),
       (long) (stop_t.tv_usec - start_t.tv_usec) % 1000);
  }
 }

 free(array);
 free(reslt);
 free(bufnm);

 return 0;
}




pgsql-patches by date:

Previous
From: "William ZHANG"
Date:
Subject: Re: Bug in canonicalize_path()
Next
From: Tom Lane
Date:
Subject: Re: Bug in canonicalize_path()