Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package Oxo;
- import Oxo.agents.GameUtils;
- import Oxo.agents.MiniMaxAgent;
- import Oxo.agents.MiniMaxAgentFJ;
- import Oxo.agents.RandomAgent;
- import Oxo.games.oxo.Oxo;
- import Oxo.games.oxo.OxoBoardTooLargeException;
- import Oxo.games.oxo.heuristics.SimpleScoreHeuristic;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.List;
- import java.util.Random;
- /**
- * Created by christophe on 5/29/14.
- * <p/>
- * This class serves the purpose of benchmarking the Fork/Join code
- * implemented by myself. It will run the code with ranges of parameters
- * which is required for the report.
- * The only thing I actually want to measure is what difference the
- * sequential cutt-off makes on the performance of the fork/join algorithm.
- */
- public class Benchmark {
- /**
- * This function simply plays a game of Oxo. We don't care about the results.
- * We do return the results however to make sure that the JIT does not optimize this code
- * such that it does not get executed.
- *
- * @param height Dimensions of the game board.
- * @param width
- * @param player1 Both players that will be playing the game.
- * @param player2
- * @throws OxoBoardTooLargeException
- */
- private static double[] PlayGame(int height, int width, Agent<? super Oxo> player1, Agent<? super Oxo> player2) throws OxoBoardTooLargeException {
- // Create the game board.
- Oxo game = new Oxo(height, width);
- // Add the players to the game.
- List<Agent<? super Oxo>> players = new ArrayList<>(2);
- players.add(player1);
- players.add(player2);
- // Play the actual game.
- //System.gc(); TODO is this needed?
- return playGame(game, players);
- }
- private static double[] PlayFirstMove(int height, int width, Agent<? super Oxo> player1) throws OxoBoardTooLargeException {
- // Create the game board.
- Oxo game = new Oxo(height, width);
- return playFirstMoveOnly(game, player1);
- }
- private static <G extends Game> double[] playFirstMoveOnly(G game, Agent<? super G> player){
- player.setId(0);
- game.start();
- int action = player.act(game);
- game.performAction(action);
- return game.getScores();
- }
- public static int main(String[] args) throws OxoBoardTooLargeException {
- int dummy = 0; // Dummy value to stop optimisations.
- /**
- * /!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\/!\
- * For the warmup it is important that we use the XX:CompileThreshold=100 flag.
- * This reduces warmuptime severely.
- *
- * Part one 1
- * ==========
- * This test will be used to show the raw performance difference between the sequential
- * and f/j implementation. To this end we will see how long a move takes for each implementation.
- * This part will run a test where we will use a thhold of zero.
- * This means that all evaluation will be run solely with the f/j part.
- * This should give us a baseline for comparing performance. We will run
- * the test with increasing board size.
- *
- * For the warm-up phase we execute each agent 100 times. This should trigger the compilation
- * to native code and thus make sure we have no skewed results.
- */
- /**************************/
- /******* Warm-up ***********/
- /**************************/
- // Create two players. They will be the same throughout the warm-up
- // so we might as well keep them.
- int lookahead = 4;
- int thhold = 0;
- /*
- MiniMaxAgentFJ<Oxo> FJAgent = new MiniMaxAgentFJ<>(lookahead, new SimpleScoreHeuristic(), thhold);
- MiniMaxAgent<Oxo> SequentialAgent = new MiniMaxAgent<>(lookahead, new SimpleScoreHeuristic(), new Random());
- System.out.println("Warm-up phase");
- for (int j = 0; j <= 100; j++) {
- // Play the move.
- double[] scores = PlayFirstMove(3, 3, FJAgent );
- double[] scores2 = PlayFirstMove(3, 3, SequentialAgent);
- // Simple hack to make sure dead code is not gone in compilation.
- dummy |= scores.hashCode();
- dummy |= scores2.hashCode();
- // Print out warm-up progress.
- System.out.print("\r" + j + "%");
- }*/
- /**************************/
- /******* Load * ***********/
- /**************************/
- // Determine the "most square" board dimensions for each number of fields.
- /* ArrayList<Integer[]> boardDimensions = GameUtils.BoardDimensions((int) (Math.log(Long.MAX_VALUE) / Math.log(3)));
- // Run the test with the sequential algorithm as a baseline.
- System.out.printf("%nTest1%nagenttype ; thhold; lookahead; gamesize; miliseconds;%n");
- for (Integer[] dimension : boardDimensions) {
- // Variables for timings.
- long before;
- long after;
- // Board dimensions.
- int width = dimension[0];
- int height = dimension[1];
- // Time for fork/join implementation.
- before = System.nanoTime();
- double[] scores = PlayFirstMove(width, height, FJAgent);
- after = System.nanoTime();
- long totalTime = after-before;
- System.out.printf("forkjoin ;%7d; %9d; %8d; %15d; %n", thhold, lookahead, (width * height), (int) Math.ceil(totalTime / 1000000));
- // Time sequential implementation.
- before = System.nanoTime();
- double[] scores2 = PlayFirstMove(width, height, SequentialAgent);
- after = System.nanoTime();
- long totalTime2 = after - before;
- System.out.printf("sequential;%7d; %9d; %8d; %15d; %n", thhold, lookahead, (width * height), (int) Math.ceil(totalTime2 / 1000000));
- // Trick the JVM.
- dummy |= Arrays.hashCode(scores);
- dummy |= Arrays.hashCode(scores2);
- }*/
- /**
- * Part 2
- * ======
- * This test will simply test what the best thhold is. To this end we will have a static boardsize and a
- * static lookahead. The lookahead shoud be sufficient however. If we want to test a big enough range of
- * thhold we will need to have a lookahead that is at least as much as the maximum thhold.
- *
- * As boardsize we use 5*5 which is not the biggest board size, but it gives us reasonable benchmark times.
- *
- * As a lookahead we will us 13. This is because the deepest the gametree can get is size/2 is 13.
- * The thhold will be increased from 0 to 13. Which is the maximum lookahead possible in a game of 25 squares.
- */
- /****************************/
- /******** Warmup ************/
- /****************************/
- // Variables for warm-up.
- lookahead = 7;
- int height = 3;
- int width = 3;
- MiniMaxAgentFJ<Oxo> FJPlayer = new MiniMaxAgentFJ<>(lookahead, new SimpleScoreHeuristic(), 0);
- System.out.println("Warm-up phase");
- for(int i = 0; i <= 100; i++)
- {
- // Just make the first move.
- double[] scores = PlayFirstMove(height, width, FJPlayer);
- // Trick the JVM.
- dummy |= Arrays.hashCode(scores);
- System.out.print("\r" + i + "%");
- }
- System.out.println("\nWarmup done");
- /****************************/
- /******** Load * ************/
- /****************************/
- System.out.printf("agenttype; threshold; lookahead; gamesize; miliseconds;%n");
- lookahead = 7;
- height = 3;
- width = 3;
- int maxThreshold = lookahead;
- for(int threshold = 0; threshold < maxThreshold; threshold++)
- {
- // Change the threshold for the agent.
- //FJPlayer.setThreshold(threshold);
- MiniMaxAgentFJ<Oxo> FJPlayer2 = new MiniMaxAgentFJ<>(lookahead, new SimpleScoreHeuristic(), threshold);
- long before = System.nanoTime();
- double[] scores = PlayFirstMove(height, width, FJPlayer2);
- long after = System.nanoTime();
- long totalTime = after-before;
- // Trick the JVM.
- dummy |= Arrays.hashCode(scores);
- // Print out the resulsts.
- System.out.printf("forkjoin ;%9d; %9d; %8d; %11d; %n", threshold, lookahead, (height * width), (int) Math.ceil(totalTime / 1000000));
- }
- return dummy;
- }
- /**
- * Plays a given game using a given list of players.<br>
- * Note: The game is played from start to end. If the game was already started, it will be restarted.
- *
- * @param game to be played
- * @param players who will play the game (order = in-game id)
- * @return scores of the players at the end of the game
- */
- private static <G extends Game> double[] playGame(G game, List<? extends Agent<? super G>> players) {
- int id = 0;
- for (Agent<? super G> player : players) {
- player.setId(id);
- id++;
- }
- // Set the number of plays, turns, fields and scores.
- game.start();
- while (!game.isDone()) {
- int action = players.get(game.getTurn()).act(game);
- game.performAction(action);
- }
- return game.getScores();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement