i386/133967: The same asm-code is executed different time on
WinXp&Linux than on FreeBSD
Vasilii
vv40in at rambler.ru
Fri Apr 24 13:30:05 UTC 2009
>Number: 133967
>Category: i386
>Synopsis: The same asm-code is executed different time on WinXp&Linux than on FreeBSD
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-i386
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Fri Apr 24 13:30:04 UTC 2009
>Closed-Date:
>Last-Modified:
>Originator: Vasilii
>Release: FreeBSD 7.1
>Organization:
Special Technologies
>Environment:
FreeBSD omega.so 7.1-RELEASE FreeBSD 7.1-RELEASE #17: Fri Apr 24 20:19:44 MSD 2009 v40 at omega.so:/usr/obj/usr/src/sys/Omega i386
>Description:
i has comp: processor i7 with 4 cores (HTT enabled/disabled was checked too)
and WinXP,Linux and FreeBSD on it.
The same asm-code is executed different time on WinXp&Linux than on FreeBSD! Why?
May be i do (not) need point some compiler switches to build FreeBSD core?
the follow section contains the code which describes the situation.
>How-To-Repeat:
/*
gcc flags:
CFLAGS = -DNDEBUG -D__FREEBSD__ -fomit-frame-pointer -W -Wall
CFLAGS += -O3 -march=i686
CFLAGS += -fno-guess-branch-probability
CFLAGS += -std=c99
*/
#if !defined(_MSC_VER)
#define __FREEBSD__ //comment it
#if !defined(__FREEBSD__)
#define __LINUX__
#endif
#endif
#if defined(__FREEBSD__)
#undef __LINUX__
#endif
#if defined(__LINUX__)
#undef __FREEBSD__
#endif
#if defined(_MSC_VER) || defined(_WIN32) || defined(WIN32)
#include <Windows.h>
#endif
#include <stdio.h>
#include <time.h>
#if defined(__CYGWIN__) // !defined(_MSC_VER)
#include <basetyps.h>
#elif !defined(_MSC_VER)
#include <stdint.h>
#endif
typedef unsigned long u32;
#ifdef _MSC_VER
typedef unsigned __int64 u64;
#else
typedef uint64_t u64;
#endif
u64 overclock()
{
#ifndef _MSC_VER
clock_t t2, t1 = clock();
do {
t2 = clock();
} while (t1 == t2);
return t2;
#else
FILETIME t1,t2;
GetSystemTimeAsFileTime(&t1);
do {
GetSystemTimeAsFileTime(&t2);
} while (t1.dwLowDateTime == t2.dwLowDateTime);
return (((u64)(t2.dwHighDateTime)) << 32) + t2.dwLowDateTime;
#endif
}
u64 myclock()
{
#ifndef _MSC_VER
return clock();
#else
FILETIME t;
GetSystemTimeAsFileTime(&t);
return (((u64)(t.dwHighDateTime)) << 32) + t.dwLowDateTime;
#endif
}
void print_dtime(const char* s, u64* t1, u64* t2)
{
#ifdef _MSC_VER
double dt = ((double)(__int64)(*t2-*t1)) / 10000.0;
fprintf(stderr, "%s%I64u = %f ms\n", s, (*t2-*t1), dt);
#elif defined(__LINUX__)
double dt = ((double)(*(clock_t*)(t2) - *(clock_t*)(t1))) ;/// 10000.0;
fprintf(stderr, "%s%f ms \n", s, dt*1000000.0);
#else //if defined(__FREEBSD__)
double dt = ((double)(*(clock_t*)(t2) - *(clock_t*)(t1))) ;/// 10000.0;
fprintf(stderr, "%s%f ms \n", s, dt*10.0);
#endif
fflush(stderr);
}
//#include "getopt.h"
//#include "thetypes.h"
volatile unsigned int buf[0x10000];
#define _MAX_CNT ((1<<17 )-1)
#define _MAX_BUF_CNT 0x10
int test()
{
u32 i=0,j=0;
u64 t1,t2;
for (i=0; i<_MAX_BUF_CNT; ++i)
buf[i]=0;
printf("start\n");
t1 = overclock();
#ifdef __FREEBSD__
//gccalign8;
__asm__ __volatile__(
"nop;nop; \n" /* to align code to 16 bytes as MSVC. i selected it manually */
"xorl %%edi,%%edi \n\t"
"jmp 30f \n"
"nop;nop;nop;nop; \n" /* to align code to 16 bytes as MSVC. */
"nop;nop;nop;nop; \n"
"nop;nop;nop;nop; \n"
"\n30:\n\t"
"xorl %%esi,%%esi \n\t"
"jmp 1f \n"
"1: \n\t"
"leal (%%esi,%%edi), %%ecx \n\t"
"andl $0x0F, %%ecx \n\t"
"movl %%esi, (%%edx,%%ecx,4) \n\t"
"addl $1, %%esi \n\t"
"cmpl $0x1FFFF, %%esi \n\t"
"jb 1b \n\t "
"add $1, %%edi \n\t"
"cmpl $0x1FFFF, %%edi \n\t"
"jb 30b \n\t "
:
: "d"(buf)
:"esi","edi"
);
#else
for (i=0; i<_MAX_CNT; ++i)
for (j=0; j<_MAX_CNT; ++j)
buf[(i+j)&(_MAX_BUF_CNT-1)] = j;
/*
MSVC disasm:
00401055 xor edi,edi
00401057 jmp test+60h (401060h)
00401059 lea esp,[esp]
94: {
95: for (j=0; j<_MAX_CNT; ++j)
00401060 xor esi,esi ;;;code aligned to 16 bytes
00401062 jmp test+70h (401070h)
... ;filler-code to align code to 16 bytes
96: {
97: buf[(i+j)&(0x10000-1)] = j;
00401070 lea ecx,[esi+edi] ;;;code aligned to 16 bytes
00401073 and ecx,0Fh
00401079 mov dword ptr _buf (4033A0h)[ecx*4],esi
00401080 add esi,1
00401083 cmp esi,1FFFFh
00401089 jb test+70h (401070h)
0040108B add edi,1
0040108E cmp edi,1FFFFh
00401094 jb test+60h (401060h)
*/
#endif
t2 = myclock();
print_dtime("finish ", &t1, &t2);
printf("finish i,j (%u,%u)\n",i,j);
return 0;
}
int main(int argc, char* argv[])
{
test();
return 0;
}
>Fix:
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-i386
mailing list