Advertisement
m1dnight

Untitled

Jun 3rd, 2014
508
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 9.53 KB | None | 0 0
  1. package Oxo;
  2.  
  3. import Oxo.agents.GameUtils;
  4. import Oxo.agents.MiniMaxAgent;
  5. import Oxo.agents.MiniMaxAgentFJ;
  6. import Oxo.agents.RandomAgent;
  7. import Oxo.games.oxo.Oxo;
  8. import Oxo.games.oxo.OxoBoardTooLargeException;
  9. import Oxo.games.oxo.heuristics.SimpleScoreHeuristic;
  10.  
  11. import java.util.ArrayList;
  12. import java.util.Arrays;
  13. import java.util.List;
  14. import java.util.Random;
  15.  
  16. /**
  17.  * Created by christophe on 5/29/14.
  18.  * <p/>
  19.  * This class serves the purpose of benchmarking the Fork/Join code
  20.  * implemented by myself. It will run the code with ranges of parameters
  21.  * which is required for the report.
  22.  * The only thing I actually want to measure is what difference the
  23.  * sequential cutt-off makes on the performance of the fork/join algorithm.
  24.  */
  25. public class Benchmark {
  26.     /**
  27.      * This function simply plays a game of Oxo. We don't care about the results.
  28.      * We do return the results however to make sure that the JIT does not optimize this code
  29.      * such that it does not get executed.
  30.      *
  31.      * @param height  Dimensions of the game board.
  32.      * @param width
  33.      * @param player1 Both players that will be playing the game.
  34.      * @param player2
  35.      * @throws OxoBoardTooLargeException
  36.      */
  37.     private static double[] PlayGame(int height, int width, Agent<? super Oxo> player1, Agent<? super Oxo> player2) throws OxoBoardTooLargeException {
  38.         // Create the game board.
  39.         Oxo game = new Oxo(height, width);
  40.         // Add the players to the game.
  41.         List<Agent<? super Oxo>> players = new ArrayList<>(2);
  42.         players.add(player1);
  43.         players.add(player2);
  44.         // Play the actual game.
  45.         //System.gc(); TODO is this needed?
  46.         return playGame(game, players);
  47.     }
  48.     private static double[] PlayFirstMove(int height, int width, Agent<? super Oxo> player1) throws OxoBoardTooLargeException {
  49.         // Create the game board.
  50.         Oxo game = new Oxo(height, width);
  51.         return playFirstMoveOnly(game, player1);
  52.     }
  53.     private static <G extends Game> double[] playFirstMoveOnly(G game, Agent<? super G> player){
  54.         player.setId(0);
  55.         game.start();
  56.         int action = player.act(game);
  57.         game.performAction(action);
  58.         return game.getScores();
  59.     }
  60.  
  61.     public static int main(String[] args) throws OxoBoardTooLargeException {
  62.         int dummy = 0; // Dummy value to stop optimisations.
  63.         /**
  64.          * /!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\
  65.          * For the warmup it is important that we use the XX:CompileThreshold=100 flag.
  66.          * This reduces warmuptime severely.
  67.          *
  68.          * Part one 1
  69.          * ==========
  70.          * This test will be used to show the raw performance difference between the sequential
  71.          * and f/j implementation. To this end we will see how long a move takes for each implementation.
  72.          * This part will run a test where we will use a thhold of zero.
  73.          * This means that all evaluation will be run solely with the f/j part.
  74.          * This should give us a baseline for comparing performance. We will run
  75.          * the test with increasing board size.
  76.          *
  77.          * For the warm-up phase we execute each agent 100 times. This should trigger the compilation
  78.          * to native code and thus make sure we have no skewed results.
  79.          */
  80.         /**************************/
  81.         /******* Warm-up ***********/
  82.         /**************************/
  83.         // Create two players. They will be the same throughout the warm-up
  84.         // so we might as well keep them.
  85.         int lookahead = 4;
  86.         int thhold    = 0;
  87.         /*
  88.  
  89.         MiniMaxAgentFJ<Oxo>       FJAgent = new MiniMaxAgentFJ<>(lookahead, new SimpleScoreHeuristic(), thhold);
  90.         MiniMaxAgent<Oxo> SequentialAgent = new MiniMaxAgent<>(lookahead, new SimpleScoreHeuristic(), new Random());
  91.  
  92.         System.out.println("Warm-up phase");
  93.         for (int j = 0; j <= 100; j++) {
  94.             // Play the move.
  95.             double[] scores  = PlayFirstMove(3, 3, FJAgent        );
  96.             double[] scores2 = PlayFirstMove(3, 3, SequentialAgent);
  97.  
  98.             // Simple hack to make sure dead code is not gone in compilation.
  99.             dummy |=  scores.hashCode();
  100.             dummy |= scores2.hashCode();
  101.  
  102.             // Print out warm-up progress.
  103.             System.out.print("\r" + j + "%");
  104.         }*/
  105.         /**************************/
  106.         /******* Load * ***********/
  107.         /**************************/
  108.         // Determine the "most square" board dimensions for each number of fields.
  109. /*        ArrayList<Integer[]> boardDimensions = GameUtils.BoardDimensions((int) (Math.log(Long.MAX_VALUE) / Math.log(3)));
  110.  
  111.         // Run the test with the sequential algorithm as a baseline.
  112.         System.out.printf("%nTest1%nagenttype ; thhold; lookahead; gamesize; miliseconds;%n");
  113.         for (Integer[] dimension : boardDimensions) {
  114.             // Variables for timings.
  115.             long before;
  116.             long after;
  117.             // Board dimensions.
  118.             int width = dimension[0];
  119.             int height = dimension[1];
  120.  
  121.             // Time for fork/join implementation.
  122.             before          = System.nanoTime();
  123.             double[] scores = PlayFirstMove(width, height, FJAgent);
  124.             after           = System.nanoTime();
  125.             long totalTime  = after-before;
  126.             System.out.printf("forkjoin  ;%7d; %9d; %8d; %15d; %n", thhold, lookahead, (width * height), (int) Math.ceil(totalTime  / 1000000));
  127.  
  128.             // Time sequential implementation.
  129.             before           = System.nanoTime();
  130.             double[] scores2 = PlayFirstMove(width, height, SequentialAgent);
  131.             after            = System.nanoTime();
  132.             long totalTime2  = after - before;
  133.             System.out.printf("sequential;%7d; %9d; %8d; %15d; %n", thhold, lookahead, (width * height), (int) Math.ceil(totalTime2 / 1000000));
  134.  
  135.             // Trick the JVM.
  136.             dummy |= Arrays.hashCode(scores);
  137.             dummy |= Arrays.hashCode(scores2);
  138.         }*/
  139.         /**
  140.          * Part 2
  141.          * ======
  142.          * This test will simply test what the best thhold is. To this end we will have a static boardsize and a
  143.          * static lookahead. The lookahead shoud be sufficient however. If we want to test a big enough range of
  144.          * thhold we will need to have a lookahead that is at least as much as the maximum thhold.
  145.          *
  146.          * As boardsize we use 5*5 which is not the biggest board size, but it gives us reasonable benchmark times.
  147.          *
  148.          * As a lookahead we will us 13. This is because the deepest the gametree can get is size/2 is 13.
  149.          * The thhold will be increased from 0 to 13. Which is the maximum lookahead possible in a game of 25 squares.
  150.          */
  151.         /****************************/
  152.         /******** Warmup ************/
  153.         /****************************/
  154.         // Variables for warm-up.
  155.         lookahead  = 7;
  156.         int height = 3;
  157.         int width  = 3;
  158.         MiniMaxAgentFJ<Oxo> FJPlayer = new MiniMaxAgentFJ<>(lookahead, new SimpleScoreHeuristic(), 0);
  159.  
  160.         System.out.println("Warm-up phase");
  161.         for(int i = 0; i <= 100; i++)
  162.         {
  163.             // Just make the first move.
  164.             double[] scores = PlayFirstMove(height, width, FJPlayer);
  165.             // Trick the JVM.
  166.             dummy |= Arrays.hashCode(scores);
  167.             System.out.print("\r" + i + "%");
  168.         }
  169.         System.out.println("\nWarmup done");
  170.  
  171.         /****************************/
  172.         /******** Load * ************/
  173.         /****************************/
  174.         System.out.printf("agenttype; threshold; lookahead; gamesize; miliseconds;%n");
  175.  
  176.         lookahead  = 7;
  177.         height     = 3;
  178.         width      = 3;
  179.         int maxThreshold = lookahead;
  180.  
  181.         for(int threshold = 0; threshold < maxThreshold; threshold++)
  182.         {
  183.             // Change the threshold for the agent.
  184.             //FJPlayer.setThreshold(threshold);
  185.             MiniMaxAgentFJ<Oxo> FJPlayer2 = new MiniMaxAgentFJ<>(lookahead, new SimpleScoreHeuristic(), threshold);
  186.  
  187.             long before     = System.nanoTime();
  188.             double[] scores = PlayFirstMove(height, width, FJPlayer2);
  189.             long after      = System.nanoTime();
  190.             long totalTime  = after-before;
  191.  
  192.             // Trick the JVM.
  193.             dummy |= Arrays.hashCode(scores);
  194.             // Print out the resulsts.
  195.             System.out.printf("forkjoin ;%9d; %9d; %8d; %11d; %n", threshold, lookahead, (height * width), (int) Math.ceil(totalTime  / 1000000));
  196.         }
  197.         return dummy;
  198.  
  199.     }
  200.  
  201.     /**
  202.      * Plays a given game using a given list of players.<br>
  203.      * Note: The game is played from start to end. If the game was already started, it will be restarted.
  204.      *
  205.      * @param game    to be played
  206.      * @param players who will play the game (order = in-game id)
  207.      * @return scores of the players at the end of the game
  208.      */
  209.     private static <G extends Game> double[] playGame(G game, List<? extends Agent<? super G>> players) {
  210.         int id = 0;
  211.         for (Agent<? super G> player : players) {
  212.             player.setId(id);
  213.             id++;
  214.         }
  215.         // Set the number of plays, turns, fields and scores.
  216.         game.start();
  217.  
  218.         while (!game.isDone()) {
  219.             int action = players.get(game.getTurn()).act(game);
  220.             game.performAction(action);
  221.         }
  222.         return game.getScores();
  223.     }
  224. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement