lkml.org 
[lkml]   [2004]   [Nov]   [1]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    From
    SubjectRe: Semaphore assembly-code bug
    On Mon, 1 Nov 2004, linux-os wrote:

    > On Mon, 1 Nov 2004, dean gaudet wrote:
    >
    > > On Sun, 31 Oct 2004, linux-os wrote:
    > >
    > > > Timer overhead = 88 CPU clocks
    > > > push 3, pop 3 = 12 CPU clocks
    > > > push 3, pop 2 = 12 CPU clocks
    > > > push 3, pop 1 = 12 CPU clocks
    > > > push 3, pop none using ADD = 8 CPU clocks
    > > > push 3, pop none using LEA = 8 CPU clocks
    > > > push 3, pop into same register = 12 CPU clocks
    > >
    > > your microbenchmark makes assumptions about rdtsc which haven't been valid
    > > since the days of the 486. rdtsc has serializing aspects and overhead that
    > > you can't just eliminate by running it in a tight loop and subtracting out
    > > that "overhead".
    > >
    >
    > Wrong.

    if you were correct then i should be able to measure 1 cycle differences
    in sequences such as the following:

    rdtsc
    mov %eax,%edi
    shr $1,%ecx
    rdtsc

    rdtsc
    mov %eax,%edi
    shr $1,%ecx
    shr $1,%ecx
    rdtsc
    ...
    rdtsc
    mov %eax,%edi
    shr $1,%ecx
    shr $1,%ecx
    shr $1,%ecx
    shr $1,%ecx
    shr $1,%ecx
    shr $1,%ecx
    shr $1,%ecx
    shr $1,%ecx
    rdtsc

    yet the attached program demonstrates that such measurements are
    inaccurate. the results should be a sequence of numbers increasing
    by 1 each time.

    p4 model 2: 80 80 84 84 84 84 84 84
    p4 model 3: 120 120 120 120 120 120 120 128
    p-m model 9: 47 46 47 48 49 50 56 57
    k8: 5 5 5 5 5 5 5 5

    -dean

    % gcc -O -o rdtsc-rounding rdtsc-rounding.c

    rdtsc-rounding.c:

    #include <stdio.h>
    #include <stdint.h>

    #define template(n) \
    static uint32_t foo##n(void) \
    { \
    uint32_t start, done, trash1, trash2; \
    \
    __asm volatile( \
    "\n rdtsc" \
    "\n mov %%eax,%0" \
    x##n("\n shr $1,%1") \
    "\n rdtsc" \
    : "=&r" (start), "=&r" (trash1), "=&a" (done), "=&d" (trash2) \
    ); \
    return done - start; \
    }

    #define x1(x) x
    #define x2(x) x x
    #define x3(x) x x x
    #define x4(x) x2(x) x2(x)
    #define x5(x) x4(x) x
    #define x6(x) x3(x2(x))
    #define x7(x) x6(x) x
    #define x8(x) x4(x2(x))

    template(1)
    template(2)
    template(3)
    template(4)
    template(5)
    template(6)
    template(7)
    template(8)

    static uint32_t (*fn[9])(void) = {
    0, foo1, foo2, foo3, foo4, foo5, foo6, foo7, foo8
    };


    static uint32_t bench(uint32_t (*f)(void))
    {
    uint32_t best;
    unsigned i;

    best = ~0;
    for (i = 0; i < 100000; ++i) {
    uint32_t cur = f();
    if (cur < best) {
    best = cur;
    }
    }
    return best;
    }


    int main(int argc, char **argv)
    {
    unsigned i;

    for (i = 1; i < sizeof(fn)/sizeof(fn[0]); ++i) {
    printf("%u ", bench(fn[i]));
    }
    printf("\n");
    return 0;
    }
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2005-03-22 14:07    [W:0.026 / U:1.904 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site