InstructionBenchmark.java
     1: //========================================================================================
     2: //  InstructionBenchmark.java
     3: //    en:Instruction Benchmark
     4: //    ja:命令ベンチマーク
     5: //  Copyright (C) 2003-2021 Makoto Kamada
     6: //
     7: //  This file is part of the XEiJ (X68000 Emulator in Java).
     8: //  You can use, modify and redistribute the XEiJ if the conditions are met.
     9: //  Read the XEiJ License for more details.
    10: //  https://stdkmd.net/xeij/
    11: //========================================================================================
    12: 
    13: //----------------------------------------------------------------------------------------
    14: //  make test PARAM="-bench=all"
    15: //  Bitrev                  1.43ns  0x0f801f3c
    16: //  Byterev                 0.20ns  0x782750ec
    17: //  BtstReg                 3.62ns  0x764fd938
    18: //  MoveToDRWord            3.31ns  0x06d60d1c
    19: //  TstByte                 1.98ns  0x2c8154cc
    20: //  SubToRegByte            4.73ns  0x7904466e
    21: //  SubToRegWord            4.73ns  0xc7f21ecc
    22: //  SubToRegLong            3.63ns  0xeb91420d
    23: //  AddToRegByte            4.81ns  0xa71b4bb9
    24: //  AddToRegWord            4.80ns  0x94701f5f
    25: //  AddToRegLong            3.90ns  0x91d02c44
    26: //  AddToMemByte            9.46ns  0x75421c12
    27: //----------------------------------------------------------------------------------------
    28: 
    29: package xeij;
    30: 
    31: import java.lang.*;  //Boolean,Character,Class,Comparable,Double,Exception,Float,IllegalArgumentException,Integer,Long,Math,Number,Object,Runnable,SecurityException,String,StringBuilder,System
    32: 
    33: public class InstructionBenchmark {
    34: 
    35:   public static final int IRB_N = 100000000;
    36:   public static final int IRB_M = 5;
    37: 
    38:   public static void irbBench (String choice) {
    39:     XEiJ.mpuInit ();
    40:     if (InstructionBreakPoint.IBP_ON) {
    41:       InstructionBreakPoint.ibpInit ();  //IBP 命令ブレークポイント
    42:     }
    43:     if (DataBreakPoint.DBP_ON) {
    44:       DataBreakPoint.dbpInit ();  //DBP データブレークポイント
    45:     }
    46:     XEiJ.busInit ();  //BUS バスコントローラ
    47:     MainMemory.mmrInit ();  //MMR メインメモリ
    48: 
    49:     boolean all = choice.equals ("all");
    50:     try {
    51:       for (IRBEnum irb : IRBEnum.values ()) {
    52:         String name = irb.name ();
    53:         if (all || name.equals (choice)) {
    54:           int sum = 0;
    55:           long best = 0x7fffffffffffffffL;
    56:           for (int i = 0; i < IRB_M; i++) {
    57:             long t0 = System.nanoTime ();
    58:             sum = irb.bench (false);
    59:             long t1 = System.nanoTime ();
    60:             sum = irb.bench (true);
    61:             t0 = System.nanoTime ();
    62:             sum = irb.bench (false);
    63:             t1 = System.nanoTime ();
    64:             sum = irb.bench (true);
    65:             long t2 = System.nanoTime ();
    66:             best = Math.min (best, (t2 - t1) - (t1 - t0));
    67:           }
    68:           System.out.printf ("%-20s  %6.2fns  0x%08x\n", name, best / (double) IRB_N, sum);
    69:         }
    70:       }
    71:     } catch (M68kException e) {
    72:     }
    73:   }  //irbBench(String)
    74: 
    75: }  //class InstructionBenchmark
    76: 
    77: 
    78: 
    79: enum IRBEnum {
    80: 
    81:   Bitrev {
    82:     @Override public int bench (boolean f) throws M68kException {
    83:        int sum = 0;
    84:        XEiJ.regOC = 0b0000_000_011_000_000 | 0 << 0;  //BITREV.L D0
    85:        for (int i = 0; i < InstructionBenchmark.IRB_N; i++) {
    86:          XEiJ.regRn[0] = i << i | i >>> -i;
    87:          XEiJ.regCCR = XEiJ.REG_CCR_MASK & i;
    88:          if (f) {
    89:            MC68000.irpCmp2Chk2Byte ();
    90:          }
    91:          sum = sum * 3 + XEiJ.regRn[0];
    92:          sum = sum * 3 + XEiJ.regCCR;
    93:        }
    94:        return sum;
    95:      }
    96:   },
    97: 
    98:   Byterev {
    99:     @Override public int bench (boolean f) throws M68kException {
   100:        int sum = 0;
   101:        XEiJ.regOC = 0b0000_001_011_000_000 | 0 << 0;  //BYTEREV.L D0
   102:        for (int i = 0; i < InstructionBenchmark.IRB_N; i++) {
   103:          XEiJ.regRn[0] = i << i | i >>> -i;
   104:          XEiJ.regCCR = XEiJ.REG_CCR_MASK & i;
   105:          if (f) {
   106:            MC68000.irpCmp2Chk2Word ();
   107:          }
   108:          sum = sum * 3 + XEiJ.regRn[0];
   109:          sum = sum * 3 + XEiJ.regCCR;
   110:        }
   111:        return sum;
   112:      }
   113:   },
   114: 
   115:   BtstReg {
   116:     @Override public int bench (boolean f) throws M68kException {
   117:        int sum = 0;
   118:        XEiJ.regOC = 0b0000_000_100_000_000 | 1 << 9 | XEiJ.EA_DR | 0 << 0;  //BTST.L D1,D0
   119:        for (int i = 0; i < InstructionBenchmark.IRB_N; i++) {
   120:          XEiJ.regRn[0] = i << i | i >>> -i;
   121:          XEiJ.regRn[1] = i << -i | i >>> i;
   122:          XEiJ.regCCR = XEiJ.REG_CCR_MASK & i;
   123:          if (f) {
   124:            MC68000.irpBtstReg ();
   125:          }
   126:          sum = sum * 3 + XEiJ.regCCR;
   127:        }
   128:        return sum;
   129:      }
   130:   },
   131: 
   132:   MoveToDRWord {
   133:     @Override public int bench (boolean f) throws M68kException {
   134:        int sum = 0;
   135:        XEiJ.regOC = 0b0011_000_000_000_000 | 0 << 9 | XEiJ.EA_DR | 1 << 0;  //MOVE.W D1,D0
   136:        for (int i = 0; i < InstructionBenchmark.IRB_N / 2; i++) {
   137:          XEiJ.regRn[0] = i << i | i >>> -i;
   138:          XEiJ.regRn[1] = i << -i | i >>> i;
   139:          XEiJ.regCCR = XEiJ.REG_CCR_MASK & i;
   140:          if (f) {
   141:            MC68000.irpMoveToDRWord ();
   142:          }
   143:          sum = sum * 3 + XEiJ.regRn[0];
   144:          sum = sum * 3 + XEiJ.regCCR;
   145:        }
   146:        XEiJ.regOC = 0b0011_000_000_000_000 | 0 << 9 | XEiJ.EA_MM | 0 << 0;  //MOVE.W (A0),D0
   147:        XEiJ.regRn[8] = 0x00200000;
   148:        for (int i = 0; i < InstructionBenchmark.IRB_N / 2; i++) {
   149:          XEiJ.regRn[0] = i << i | i >>> -i;
   150:          int t = i << -i | i >>> i;
   151:          MainMemory.mmrM8[0x00200000] = (byte) (t >> 8);
   152:          MainMemory.mmrM8[0x00200001] = (byte) t;
   153:          XEiJ.regCCR = XEiJ.REG_CCR_MASK & i;
   154:          if (f) {
   155:            MC68000.irpMoveToDRWord ();
   156:          }
   157:          sum = sum * 3 + XEiJ.regRn[0];
   158:          sum = sum * 3 + XEiJ.regCCR;
   159:        }
   160:        return sum;
   161:      }
   162:   },
   163: 
   164:   TstByte {
   165:     @Override public int bench (boolean f) throws M68kException {
   166:        int sum = 0;
   167:        XEiJ.regOC = 0b0100_101_000_000_000;  //TST.B D0
   168:        for (int i = 0; i < InstructionBenchmark.IRB_N; i++) {
   169:          XEiJ.regRn[0] = i << i | i >>> -i;
   170:          XEiJ.regCCR = XEiJ.REG_CCR_MASK & i;
   171:          if (f) {
   172:            MC68000.irpTstByte ();
   173:          }
   174:          sum = sum * 3 + XEiJ.regCCR;
   175:        }
   176:        return sum;
   177:      }
   178:   },
   179: 
   180:   TstLong {
   181:     @Override public int bench (boolean f) throws M68kException {
   182:        int sum = 0;
   183:        XEiJ.regOC = 0b0100_101_010_000_000;  //TST.L D0
   184:        for (int i = 0; i < InstructionBenchmark.IRB_N; i++) {
   185:          XEiJ.regRn[0] = i << i | i >>> -i;
   186:          XEiJ.regCCR = XEiJ.REG_CCR_MASK & i;
   187:          if (f) {
   188:            MC68000.irpTstLong ();
   189:          }
   190:          sum = sum * 3 + XEiJ.regCCR;
   191:        }
   192:        return sum;
   193:      }
   194:   },
   195: 
   196:   SubToRegByte {
   197:     @Override public int bench (boolean f) throws M68kException {
   198:        int sum = 0;
   199:        XEiJ.regOC = 0b1001_000_000_000_000 | 0 << 9 | XEiJ.EA_DR | 1 << 0;  //SUB.B D1,D0
   200:        XEiJ.regRn[0] = 0;
   201:        for (int i = 0; i < InstructionBenchmark.IRB_N; i++) {
   202:          XEiJ.regRn[1] = i << i | i >>> -i;
   203:          XEiJ.regCCR = XEiJ.REG_CCR_MASK & i;
   204:          if (f) {
   205:            MC68000.irpSubToRegByte ();
   206:          }
   207:          sum = sum * 3 + XEiJ.regRn[0];
   208:          sum = sum * 3 + XEiJ.regCCR;
   209:        }
   210:        return sum;
   211:      }
   212:   },
   213:   SubToRegWord {
   214:     @Override public int bench (boolean f) throws M68kException {
   215:        int sum = 0;
   216:        XEiJ.regOC = 0b1001_000_001_000_000 | 0 << 9 | XEiJ.EA_DR | 1 << 0;  //SUB.W D1,D0
   217:        XEiJ.regRn[0] = 0;
   218:        for (int i = 0; i < InstructionBenchmark.IRB_N; i++) {
   219:          XEiJ.regRn[1] = i << i | i >>> -i;
   220:          XEiJ.regCCR = XEiJ.REG_CCR_MASK & i;
   221:          if (f) {
   222:            MC68000.irpSubToRegWord ();
   223:          }
   224:          sum = sum * 3 + XEiJ.regRn[0];
   225:          sum = sum * 3 + XEiJ.regCCR;
   226:        }
   227:        return sum;
   228:      }
   229:   },
   230:   SubToRegLong {
   231:     @Override public int bench (boolean f) throws M68kException {
   232:        int sum = 0;
   233:        XEiJ.regOC = 0b1001_000_010_000_000 | 0 << 9 | XEiJ.EA_DR | 1 << 0;  //SUB.L D1,D0
   234:        XEiJ.regRn[0] = 0;
   235:        for (int i = 0; i < InstructionBenchmark.IRB_N; i++) {
   236:          XEiJ.regRn[1] = i << i | i >>> -i;
   237:          XEiJ.regCCR = XEiJ.REG_CCR_MASK & i;
   238:          if (f) {
   239:            MC68000.irpSubToRegLong ();
   240:          }
   241:          sum = sum * 3 + XEiJ.regRn[0];
   242:          sum = sum * 3 + XEiJ.regCCR;
   243:        }
   244:        return sum;
   245:      }
   246:   },
   247: 
   248:   AddToRegByte {
   249:     @Override public int bench (boolean f) throws M68kException {
   250:        int sum = 0;
   251:        XEiJ.regOC = 0b1101_000_000_000_000 | 0 << 9 | XEiJ.EA_DR | 1 << 0;  //ADD.B D1,D0
   252:        XEiJ.regRn[0] = 0;
   253:        for (int i = 0; i < InstructionBenchmark.IRB_N; i++) {
   254:          XEiJ.regRn[1] = i << i | i >>> -i;
   255:          XEiJ.regCCR = XEiJ.REG_CCR_MASK & i;
   256:          if (f) {
   257:            MC68000.irpAddToRegByte ();
   258:          }
   259:          sum = sum * 3 + XEiJ.regRn[0];
   260:          sum = sum * 3 + XEiJ.regCCR;
   261:        }
   262:        return sum;
   263:      }
   264:   },
   265:   AddToRegWord {
   266:     @Override public int bench (boolean f) throws M68kException {
   267:        int sum = 0;
   268:        XEiJ.regOC = 0b1101_000_001_000_000 | 0 << 9 | XEiJ.EA_DR | 1 << 0;  //ADD.W D1,D0
   269:        XEiJ.regRn[0] = 0;
   270:        for (int i = 0; i < InstructionBenchmark.IRB_N; i++) {
   271:          XEiJ.regRn[1] = i << i | i >>> -i;
   272:          XEiJ.regCCR = XEiJ.REG_CCR_MASK & i;
   273:          if (f) {
   274:            MC68000.irpAddToRegWord ();
   275:          }
   276:          sum = sum * 3 + XEiJ.regRn[0];
   277:          sum = sum * 3 + XEiJ.regCCR;
   278:        }
   279:        return sum;
   280:      }
   281:   },
   282:   AddToRegLong {
   283:     @Override public int bench (boolean f) throws M68kException {
   284:        int sum = 0;
   285:        XEiJ.regOC = 0b1101_000_010_000_000 | 0 << 9 | XEiJ.EA_DR | 1 << 0;  //ADD.L D1,D0
   286:        XEiJ.regRn[0] = 0;
   287:        for (int i = 0; i < InstructionBenchmark.IRB_N; i++) {
   288:          XEiJ.regRn[1] = i << i | i >>> -i;
   289:          XEiJ.regCCR = XEiJ.REG_CCR_MASK & i;
   290:          if (f) {
   291:            MC68000.irpAddToRegLong ();
   292:          }
   293:          sum = sum * 3 + XEiJ.regRn[0];
   294:          sum = sum * 3 + XEiJ.regCCR;
   295:        }
   296:        return sum;
   297:      }
   298:   },
   299: 
   300:   AddToMemByte {
   301:     @Override public int bench (boolean f) throws M68kException {
   302:        int sum = 0;
   303:        XEiJ.regOC = 0b1101_000_100_000_000 | 0 << 9 | XEiJ.EA_DR | 1 << 0;  //ADDX.B D1,D0
   304:        XEiJ.regRn[0] = 0;
   305:        for (int i = 0; i < InstructionBenchmark.IRB_N / 2; i++) {
   306:          XEiJ.regRn[1] = i << i | i >>> -i;
   307:          XEiJ.regCCR = XEiJ.REG_CCR_MASK & i;
   308:          if (f) {
   309:            MC68000.irpAddToMemByte ();
   310:          }
   311:          sum = sum * 3 + XEiJ.regRn[0];
   312:          sum = sum * 3 + XEiJ.regCCR;
   313:        }
   314:        XEiJ.regOC = 0b1101_000_100_000_000 | 0 << 9 | XEiJ.EA_MM | 0 << 0;  //ADD.B D0,(A0)
   315:        XEiJ.regRn[8] = 0x00200000;
   316:        MainMemory.mmrM8[0x00200000] = 0;
   317:        for (int i = 0; i < InstructionBenchmark.IRB_N / 2; i++) {
   318:          XEiJ.regRn[0] = i << i | i >>> -i;
   319:          XEiJ.regCCR = XEiJ.REG_CCR_MASK & i;
   320:          if (f) {
   321:            MC68000.irpAddToMemByte ();
   322:          }
   323:          sum = sum * 3 + (MainMemory.mmrM8[0x00200000] & 255);
   324:          sum = sum * 3 + XEiJ.regCCR;
   325:        }
   326:        return sum;
   327:      }
   328:   };
   329: 
   330:   public abstract int bench (boolean f) throws M68kException;
   331: 
   332: }  //enum IRBEnum
   333: 
   334: 
   335: