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: