Some platform-specific MemSet research

Поиск
Список
Период
Сортировка
От Seneca Cunningham
Тема Some platform-specific MemSet research
Дата
Msg-id 43D6A91C.1070601@ca.afilias.info
обсуждение исходный текст
Ответы Re: Some platform-specific MemSet research  (Martijn van Oosterhout <kleptog@svana.org>)
Список 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 по дате отправления:

Предыдущее
От: Andrew Sullivan
Дата:
Сообщение: Re: Cleaning up the INET/CIDR mess
Следующее
От: Martijn van Oosterhout
Дата:
Сообщение: Re: Some platform-specific MemSet research