Unified · Split
| @@ -13,6 +13,19 @@ enum { · 12 unmodified lines | |||
| 13 | 13 | ||
| 14 | static uvlong adj; | 14 | static uvlong adj; |
| 15 | 15 | ||
| 16 | typedef struct Res { | ||
| 17 | ulong ax, bx, cx, dx; | ||
| 18 | }Res; | ||
| 19 | |||
| 20 | Res cpuid(ulong ax, ulong cx); | ||
| 21 | |||
| 22 | void _tstart(uvlong *c); | ||
| 23 | void _tend(uvlong *c); | ||
| 24 | void _tstartp(uvlong *c); | ||
| 25 | void _tendp(uvlong *c); | ||
| 26 | void (*tstart)(uvlong *c); | ||
| 27 | void (*tend)(uvlong *c); | ||
| 28 | |||
| 16 | uvlong | 29 | uvlong |
| 17 | cycles2ns(uvlong x) | 30 | cycles2ns(uvlong x) |
| 18 | { | 31 | { |
| @@ -47,10 +60,23 @@ static int · 28 unmodified lines | |||
| 47 | void | 60 | void |
| 48 | benchinit(B *b, char *name) | 61 | benchinit(B *b, char *name) |
| 49 | { | 62 | { |
| 63 | Res r; | ||
| 50 | int i; | 64 | int i; |
| 51 | 65 | ||
| 52 | fmtinstall(L'σ', σfmt); | 66 | fmtinstall(L'σ', σfmt); |
| 53 | fmtinstall(L'τ', τfmt); | 67 | fmtinstall(L'τ', τfmt); |
| 68 | |||
| 69 | if(tstart == nil){ | ||
| 70 | r = cpuid(0x80000001, 2); | ||
| 71 | if((r.dx & (1<<27)) != 0){ | ||
| 72 | tstart = _tstartp; | ||
| 73 | tend = _tendp; | ||
| 74 | }else{ | ||
| 75 | tstart = _tstart; | ||
| 76 | tend = _tend; | ||
| 77 | } | ||
| 78 | } | ||
| 79 | |||
| 54 | memset(b, 0, sizeof(*b)); | 80 | memset(b, 0, sizeof(*b)); |
| 55 | b->name = name; | 81 | b->name = name; |
| 56 | b->n = b->nc = Bstepmin; | 82 | b->n = b->nc = Bstepmin; |
| @@ -24,11 +24,11 @@ struct B { · 23 unmodified lines | |||
| 24 | 24 | ||
| 25 | /* private */ | 25 | /* private */ |
| 26 | void benchstep(B *b); | 26 | void benchstep(B *b); |
| 27 | void _tstart(uvlong *c); | 27 | extern void (*tstart)(uvlong *c); |
| 28 | void _tend(uvlong *c); | 28 | extern void (*tend)(uvlong *c); |
| 29 | 29 | ||
| 30 | /* public */ | 30 | /* public */ |
| 31 | void benchinit(B *b, char *name); | 31 | void benchinit(B *b, char *name); |
| 32 | void benchprint(B *b, int nb, int fd); | 32 | void benchprint(B *b, int nb, int fd); |
| 33 | #define benchin(b) do{ _tstart(&(b)->tin); }while(0) | 33 | #define benchin(b) do{ tstart(&(b)->tin); }while(0) |
| 34 | #define benchout(b) do{ _tend(&(b)->tout); benchstep(b); }while(0) | 34 | #define benchout(b) do{ tend(&(b)->tout); benchstep(b); }while(0) |
| @@ -1,13 +1,37 @@ | |||
| 1 | TEXT _tstart(SB), 1, $0 | 1 | TEXT _tstart(SB), 1, $0 |
| 2 | LFENCE | 2 | CPUID |
| 3 | RDTSC | 3 | RDTSC |
| 4 | MOVL AX, 0(RARG) | 4 | MOVL AX, 0(RARG) |
| 5 | MOVL DX, 4(RARG) | 5 | MOVL DX, 4(RARG) |
| 6 | RET | 6 | RET |
| 7 | 7 | ||
| 8 | TEXT _tend(SB), 1, $0 | 8 | TEXT _tend(SB), 1, $0 |
| 9 | CPUID | ||
| 9 | RDTSC | 10 | RDTSC |
| 10 | MOVL AX, 0(RARG) | 11 | MOVL AX, 0(RARG) |
| 11 | MOVL DX, 4(RARG) | 12 | MOVL DX, 4(RARG) |
| 13 | RET | ||
| 14 | |||
| 15 | TEXT _tstartp(SB), 1, $0 | ||
| 16 | CPUID | ||
| 17 | WORD $0x010f; BYTE $0xf9 // RDTSCP | ||
| 18 | MOVL AX, 0(RARG) | ||
| 19 | MOVL DX, 4(RARG) | ||
| 20 | RET | ||
| 21 | |||
| 22 | TEXT _tendp(SB), 1, $0 | ||
| 23 | WORD $0x010f; BYTE $0xf9 // RDTSCP | ||
| 24 | MOVL AX, 0(RARG) | ||
| 25 | MOVL DX, 4(RARG) | ||
| 26 | CPUID | ||
| 27 | RET | ||
| 28 | |||
| 29 | TEXT cpuid(SB), 1, $0 | ||
| 30 | MOVL ax+8(FP), AX | ||
| 31 | MOVL cx+16(FP), CX | ||
| 12 | CPUID | 32 | CPUID |
| 33 | MOVL AX, 0(BP) | ||
| 34 | MOVL BX, 4(BP) | ||
| 35 | MOVL CX, 8(BP) | ||
| 36 | MOVL DX, 12(BP) | ||
| 13 | RET | 37 | RET |