/* * zeropg.cpp: test normal, mmx & sse clear_page() * * Copyright (C) 1999, 2001 by Manfred Spraul. * * Redistribution of this file is permitted under the terms of the GNU * Public License (GPL) * $Header: /pub/cvs/ms/movetest/zeropg.cpp,v 1.2 2001/02/08 16:02:08 manfred Exp $ */ #include #include #include #include // Intel recommends that a serializing instruction // should be called before and after rdtsc. // CPUID is a serializing instruction. // ".align 64:" the atlon has a 64 byte cache line size. #define read_rdtsc_before(time) \ __asm__ __volatile__( \ ".align 64\n\t" \ "cpuid\n\t" \ "rdtsc\n\t" \ "mov %%eax,(%0)\n\t" \ "mov %%edx,4(%0)\n\t" \ "cpuid\n\t" \ : /* no output */ \ : "S"(&time) \ : "eax", "ebx", "ecx", "edx", "memory") #define read_rdtsc_after(time) \ __asm__ __volatile__( \ "cpuid\n\t" \ "rdtsc\n\t" \ "mov %%eax,(%0)\n\t" \ "mov %%edx,4(%0)\n\t" \ "cpuid\n\t" \ : /* no output */ \ : "S"(&time) \ : "eax", "ebx", "ecx", "edx", "memory") #define BUILD_TESTFNC(name, text, instructions) \ static void name(void) \ { \ unsigned long long time; \ unsigned long long time2; \ static unsigned long best = 1024*1024*1024; \ \ read_rdtsc_before(time); \ instructions; \ read_rdtsc_after(time2); \ if(time2-time < best) { \ printf( text ": %Ld ticks; \n", \ time2-time); \ best = time2-time; \ } \ } void filler(void) { static int i = 3; static int j; j = i*i; } #define DO_3(x) \ do { x; x; x; } while(0) #define DO_T(y) do { \ DO_3(filler()); \ y; \ DO_3(filler());} while(0) #define DRAIN_SZ (4*1024*1024) int other[3*DRAIN_SZ]; static void drain_cache(void) { int i; for(i=0;i