Re: remove BufferBlockPointers for speed and space

From: "Qingqing Zhou" <zhouqq(at)cs(dot)toronto(dot)edu>
To: pgsql-patches(at)postgresql(dot)org
Subject: Re: remove BufferBlockPointers for speed and space
Date: 2005-08-12 03:29:11
Message-ID: ddh56r$bk0$1@news.hub.org
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-patches


"Tom Lane" <tgl(at)sss(dot)pgh(dot)pa(dot)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;
}

In response to

Responses

Browse pgsql-patches by date

  From Date Subject
Next Message Tom Lane 2005-08-12 03:39:21 Re: Bug in canonicalize_path()
Previous Message Bruce Momjian 2005-08-12 03:27:23 Re: [HACKERS] For review: Server instrumentation patch