lkml.org 
[lkml]   [2001]   [Nov]   [6]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    From
    SubjectRe: Using %cr2 to reference "current"
    On Tue, Nov 06, 2001 at 09:49:15AM -0800, Linus Torvalds wrote:
    > That said, how expensive is loading %cr2 anyway? We can do all the same
    > tricks with a 16kB stack and just playing games with using the higher bits
    > as the "offset", ie things like

    Here are some numbers:

    read cr2 best: 11 av: 11.12
    write cr2 cr2 best: 61 av: 64.42
    read cr2 best: 11 av: 11.12
    write cr2 cr2 best: 61 av: 65.01
    read stk best: 10 av: 11.03
    write cr2 stk best: 61 av: 64.95
    read stk best: 10 av: 11.03
    write cr2 stk best: 61 av: 65.23

    Which come from insmod of the below two modules. I didn't test writing to
    the stack register, but I expect it's similarly expensive as it affects the
    call return stack and other behind the scenes dependancies. Suffice it to
    say that reading %cr2 is essentially free on my box (athlon mp). Maybe
    we should use it as a pointer into a per-cpu area to avoid writing it?

    -ben

    ----teststk_k.c----
    #define USE_STK 1
    #include "testcr2_k.c"
    ----testcr2_k.c----
    #include <linux/module.h>
    #include <linux/kernel.h>
    #include <asm/errno.h>
    #include <linux/init.h>

    static inline long long rdtsc(void)
    {
    unsigned int low,high;
    __asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high));
    return low + (((long long)high)<<32);
    }

    long dummy;

    long doit(void)
    {
    long long start, end;
    long val;

    start = rdtsc();
    #ifdef USE_STK
    #define WHICH "stk"
    __asm__ __volatile__(
    "movl $0x0003c000,%%eax \n" // 4 bits at bit 14
    "movl $-16384,%%edx \n" // remove low 14 bits
    "andl %%esp,%%eax \n"
    "andl %%esp,%%edx \n"
    "shrl $7,%%eax \n" // color it by 128 bytes
    "addl %%edx,%%eax \n"
    : "=a" (val) :: "edx");
    #else
    #define WHICH "cr2"
    __asm__ __volatile__("movl %%cr2,%0" : "=r" (val));
    #endif
    val += 100;
    dummy = val;
    end = rdtsc();

    return end - start;
    }

    long doit2(void)
    {
    long long start, end;
    long val;

    start = rdtsc();
    val = dummy;
    __asm__ __volatile__("movl %0,%%cr2" : "=r" (val));
    end = rdtsc();

    return end - start;
    }

    int test_init (void)
    {
    long min = 1000000000, av = 0;
    int i;
    for (i=0; i<100; i++) {
    long dur = doit();
    if (dur < min)
    min = dur;
    av += dur;
    }
    printk("read " WHICH " best: %ld av: %ld.%02ld\n", min, av / 100, av % 100);

    min = 10000000;
    av = 0;
    for (i=0; i<100; i++) {
    long dur = doit2();
    if (dur < min)
    min = dur;
    av += dur;
    }
    printk("write cr2 " WHICH " best: %ld av: %ld.%02ld\n", min, av / 100, av % 100);
    return -ENODEV;
    }

    void test_exit(void)
    {
    return;
    }

    module_init(test_init);
    module_exit(test_exit);
    MODULE_LICENSE("GPL");
    ---snip---
    -
    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 13:18    [W:0.031 / U:30.004 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site