/******************************************************************************\ * Project: Simple Vector Unit Benchmark * * Authors: Iconoclast * * Release: 2013.12.12 * * License: CC0 Public Domain Dedication * * * * To the extent possible under law, the author(s) have dedicated all copyright * * and related and neighboring rights to this software to the public domain * * worldwide. This software is distributed without any warranty. * * * * You should have received a copy of the CC0 Public Domain Dedication along * * with this software. * * If not, see . * \******************************************************************************/ /* * Since operations on scalar registers are much more predictable, * standardized, and documented, we don't really need to bench those. * * I was thinking I should also add MTC0 (SP DMA and writes to SP_STATUS_REG) * and, due to the SSE-style flags register file, CFC2 and CTC2, but I mostly * just wanted to hurry up and make this header quick with all the basics. :P * * Fortunately, because all the methods are static (no conditional jumps), * we can lazily leave the instruction word set to 0x00000000 for all the * op-codes we are benching, and it will make no difference in speed. */ #include #include #include #include #include "../usf.h" #include "../usf_internal.h" #undef JUMP #define DisplayError(...) #include "config.h" #include "matrix.h" #include "rsp.h" #define NUMBER_OF_VU_OPCODES 38 ALIGNED usf_state_t state; void CheckInterrupts(usf_state_t * state) { (void)state; return; } void SP_DMA_READ(usf_state_t * state) { (void)state; return; } void SP_DMA_WRITE(usf_state_t * state) { (void)state; return; } static void (*bench_tests[NUMBER_OF_VU_OPCODES])(usf_state_t *, int, int, int, int) = { VMULF, VMACF, /* signed single-precision fractions */ VMULU, VMACU, /* unsigned single-precision fractions */ VMUDL, VMADL, /* double-precision multiplies using partial products */ VMUDM, VMADM, VMUDN, VMADN, VMUDH, VMADH, VADD, VSUB, VABS, VADDC, VSUBC, VSAW, VEQ, VNE, VLT, VGE, /* normal select compares */ VCH, VCL, /* double-precision clip select */ VCR, /* single-precision, one's complement */ VMRG, VAND, VNAND, VOR , VNOR , VXOR, VNXOR, VRCPL, VRSQL, /* double-precision reciprocal look-ups */ VRCPH, VRSQH, VMOV, VNOP }; enum { SP_VMULF = 000, SP_VMULU = 001, SP_VRNDP = 002, SP_VMULQ = 003, SP_VMUDL = 004, SP_VMUDM = 005, SP_VMUDN = 006, SP_VMUDH = 007, SP_VMACF = 010, SP_VMACU = 011, SP_VRNDN = 012, SP_VMACQ = 013, SP_VMADL = 014, SP_VMADM = 015, SP_VMADN = 016, SP_VMADH = 017, SP_VADD = 020, SP_VSUB = 021, SP_VSUT = 022, SP_VABS = 023, SP_VADDC = 024, SP_VSUBC = 025, SP_VADDB = 026, SP_VSUBB = 027, SP_VACCB = 030, SP_VSUCB = 031, SP_VSAD = 032, SP_VSAC = 033, SP_VSUM = 034, SP_VSAW = 035, SP_VLT = 040, SP_VEQ = 041, SP_VNE = 042, SP_VGE = 043, SP_VCL = 044, SP_VCH = 045, SP_VCR = 046, SP_VMRG = 047, SP_VAND = 050, SP_VNAND = 051, SP_VOR = 052, SP_VNOR = 053, SP_VXOR = 054, SP_VNXOR = 055, SP_VRCP = 060, SP_VRCPL = 061, SP_VRCPH = 062, SP_VMOV = 063, SP_VRSQ = 064, SP_VRSQL = 065, SP_VRSQH = 066, SP_VNOP = 067, SP_VEXTT = 070, SP_VEXTQ = 071, SP_VEXTN = 072, SP_VINST = 074, SP_VINSQ = 075, SP_VINSN = 076, SP_VNULLOP= 077 }; const char* test_names[NUMBER_OF_VU_OPCODES] = { mnemonics_C2[SP_VMULF], mnemonics_C2[SP_VMACF], mnemonics_C2[SP_VMULU], mnemonics_C2[SP_VMACU], mnemonics_C2[SP_VMUDL], mnemonics_C2[SP_VMADL], mnemonics_C2[SP_VMUDM], mnemonics_C2[SP_VMADM], mnemonics_C2[SP_VMUDN], mnemonics_C2[SP_VMADN], mnemonics_C2[SP_VMUDH], mnemonics_C2[SP_VMADH], mnemonics_C2[SP_VADD], mnemonics_C2[SP_VSUB], mnemonics_C2[SP_VABS], mnemonics_C2[SP_VADDC], mnemonics_C2[SP_VSUBC], mnemonics_C2[SP_VSAW], mnemonics_C2[SP_VEQ], mnemonics_C2[SP_VNE], mnemonics_C2[SP_VLT], mnemonics_C2[SP_VGE], mnemonics_C2[SP_VCH], mnemonics_C2[SP_VCL], mnemonics_C2[SP_VCR], mnemonics_C2[SP_VMRG], mnemonics_C2[SP_VAND], mnemonics_C2[SP_VNAND], mnemonics_C2[SP_VOR] , mnemonics_C2[SP_VNOR] , mnemonics_C2[SP_VXOR], mnemonics_C2[SP_VNXOR], mnemonics_C2[SP_VRCPL], mnemonics_C2[SP_VRSQL], mnemonics_C2[SP_VRCPH], mnemonics_C2[SP_VRSQH], mnemonics_C2[SP_VMOV], mnemonics_C2[SP_VNOP], }; const char* notice_starting = "Ready to start benchmarks.\n"\ "Close this message to commence tests. Testing could take minutes."; const char* notice_finished = "Finished writing benchmark results.\n"\ "Check working emulator directory for \"sp_bench.txt\"."; int main(void) { FILE* log; clock_t t1, t2; register int i, j; register float delta, total; fputs(notice_starting, stderr); log = fopen("sp_bench.txt", "w"); fprintf(log, "RSP Vector Benchmarks Log\n\n"); total = 0.0; for (i = 0; i < NUMBER_OF_VU_OPCODES; i++) { t1 = clock(); for (j = -0x1000000; j < 0; j++) bench_tests[i](&state, 0, 0, 0, 8); t2 = clock(); delta = (float)(t2 - t1) / CLOCKS_PER_SEC; fprintf(log, "%s: %.3f s\n", test_names[i], delta); fprintf(stderr, "%s: %.3f s\n", test_names[i], delta); total += delta; } fprintf(log, "Total time spent: %.3f s\n", total); fprintf(stderr, "Total time spent: %.3f s\n", total); fclose(log); fputs(notice_finished, stderr); return 0; }