Some platform-specific MemSet research - Mailing list pgsql-hackers
| From | Seneca Cunningham |
|---|---|
| Subject | Some platform-specific MemSet research |
| Date | |
| Msg-id | 43D6A91C.1070601@ca.afilias.info Whole thread Raw |
| Responses |
Re: Some platform-specific MemSet research
|
| List | pgsql-hackers |
After reading the post on -patches proposing that MemSet be changed to
use long instead of int32 on the grounds that a pair of x86-64 linux
boxes took less time to execute the long code 64*10^6 times[1], I took a
look at how the testcode performed on AIX with gcc. While the switch to
long did result in a minor performance improvement, dropping the
MemSetLoop in favour of the native memset resulted in the tests taking
~25% the time as the MemSetLoop-like int loop. The 32-bit linux system I
ran the expanded tests on showed that for the buffer size range that
postgres can use the looping MemSet instead of memset (size <= 1024
bytes), MemSet generally had better performance.
Test results, reformatted for space:
* AIX5.3 ML3
gcc version 4.0.1
OBJECT_MODE=64 gcc -maix64 -O2
sizeof(int) = 4
sizeof(long) = 8
int size=8 1.876096 1.875817 1.875998
long size=8 0.215347 0.215389 0.215367
memset size=8 0.127711 0.127726 0.127706
int size=16 0.617316 0.617346 0.617300
long size=16 0.408607 0.408294 0.408263
memset size=16 0.212843 0.176918 0.212854
int size=32 2.983032 2.982887 2.982724
long size=32 2.172499 2.172440 2.172549
memset size=32 0.255465 0.255449 0.255422
int size=64 3.560825 3.559743 3.559785
long size=64 2.974126 2.999054 2.942597
memset size=64 1.021843 1.021709 1.021704
int size=128 4.983803 4.983515 4.983236
long size=128 3.515213 3.514761 3.514733
memset size=128 1.319846 1.319699 1.319671
int size=256 9.071160 9.070497 9.070350
long size=256 7.428318 7.001997 6.990831
memset size=256 1.830684 1.830558 1.830533
int size=512 17.330519 17.329175 17.328520
long size=512 14.903931 14.902345 14.902329
memset size=512 3.512420 3.512139 3.512111
int size=1024 34.593734 34.592775 34.591700
long size=1024 23.804386 23.652192 24.043249
memset size=1024 6.010309 6.049034 6.052664
int size=2048 66.380036 66.374455 66.375010
long size=2048 45.094202 45.087909 45.087128
memset size=2048 11.638963 11.662794 11.664649
int size=4096 131.777427 131.764230 131.764542
long size=4096 88.906880 88.840758 88.887926
memset size=4096 22.882468 22.921160 22.920992
* Pentium 4 2.80GHz
Ubuntu 5.10 2.6.12-10-686 #1
gcc version 4.0.2 20050808 (prerelease) (Ubuntu 4.0.1-4ubuntu9)
gcc -O2
sizeof(int) = 4
sizeof(long) = 4
int size=8 0.319620 0.270326 0.288407
long size=8 0.279157 0.278571 0.339791
memset size=8 0.186439 0.192561 0.194865
int size=16 0.455448 0.459051 0.519848
long size=16 0.455193 0.451253 0.565159
memset size=16 0.257428 0.256752 0.356195
int size=32 0.732009 0.730730 0.750304
long size=32 0.731353 0.734311 0.743041
memset size=32 1.386004 1.404297 1.378161
int size=64 1.289708 1.397941 1.288536
long size=64 1.302256 1.380754 1.294904
memset size=64 2.965440 3.197489 2.958864
int size=128 3.162121 3.548065 3.158412
long size=128 3.150525 3.161121 3.153037
memset size=128 3.705133 3.739082 3.704949
int size=256 5.393701 5.415562 5.583510
long size=256 5.420254 5.367381 5.362041
memset size=256 9.246601 8.983931 9.040215
int size=512 10.219667 9.854537 9.851564
long size=512 9.906317 9.878196 10.202070
memset size=512 11.290588 11.050312 11.789231
int size=1024 19.777706 20.752631 19.846717
long size=1024 18.934663 18.870325 19.854066
memset size=1024 15.349694 15.487714 15.999638
int size=2048 28.783087 28.214086 26.228851
long size=2048 26.628890 30.611856 26.245331
memset size=2048 24.434751 24.095879 23.435490
int size=4096 53.817698 57.266583 51.547177
long size=4096 55.868670 53.012144 51.564656
memset size=4096 45.772710 40.651142 39.702063
[1] http://archives.postgresql.org/pgsql-patches/2006-01/msg00211.php
--
Seneca Cunningham
scunning@ca.afilias.info
#include <stdio.h>
#include <sys/time.h>
#include <string.h>
#define TYPEALIGN(ALIGNVAL,LEN) \
(((long) (LEN) + ((ALIGNVAL) - 1)) & ~((long) ((ALIGNVAL) - 1)))
#define MemSetLoop(type, start, val, len) \
do \
{ \
type * _start = (type *) (start); \
type * _stop = (type *) ((char *) _start + (size_t) (len)); \
\
while (_start < _stop) \
*_start++ = 0; \
} while (0)
#define MAXALIGN 8
#define MAXSIZE 4096
#define LOOP (1000*1000*64)
static void print_time(const char* msg, int size, const struct timeval *start, const struct timeval *end)
{
double t;
t = (end->tv_sec - start->tv_sec) + (end->tv_usec - start->tv_usec) / 1000000.0;
printf("%s (size=%d) : %f\n", msg, size, t);
}
#define TEST(type, size) \
do { \
int i; \
gettimeofday(&start, NULL); \
for(i = 0; i < LOOP; i++) \
{ \
MemSetLoop(type, buffer, 0, size); \
} \
gettimeofday(&end, NULL); \
print_time("Loop by " #type, size, &start, &end); \
} while (0)
#define TESTNATIVE(type, size) \
do { \
int i; \
gettimeofday(&start, NULL); \
for(i = 0; i < LOOP; i++) \
{ \
memset(buffer, 0, size); \
} \
gettimeofday(&end, NULL); \
print_time("memset by " #type, size, &start, &end); \
} while (0)
int main()
{
int j;
struct timeval start, end;
char buffer0[MAXSIZE + MAXALIGN];
char* buffer = (char*) TYPEALIGN(MAXALIGN, buffer0);
printf("sizeof(int) = %d\n", sizeof(int));
printf("sizeof(long) = %d\n", sizeof(long));
for(j = 0; j < 3; j++)
{
TEST(int , 8);
TESTNATIVE(int , 8);
TEST(long, 8);
TEST(int , 16);
TESTNATIVE(int , 16);
TEST(long, 16);
TEST(int , 32);
TESTNATIVE(int , 32);
TEST(long, 32);
TEST(int , 64);
TESTNATIVE(int , 64);
TEST(long, 64);
TEST(int , 128);
TESTNATIVE(int , 128);
TEST(long, 128);
TEST(int , 256);
TESTNATIVE(int , 256);
TEST(long, 256);
TEST(int , 512);
TESTNATIVE(int , 512);
TEST(long, 512);
TEST(int , 1024);
TESTNATIVE(int , 1024);
TEST(long, 1024);
TEST(int , 2048);
TESTNATIVE(int , 2048);
TEST(long, 2048);
TEST(int , 4096);
TESTNATIVE(int , 4096);
TEST(long, 4096);
}
return 0;
}
pgsql-hackers by date: