Initialization Code Runtime Reduction Effort

Jump to navigation Jump to search
Revision as of 17 February 2013 at 05:04.
The highlighted comment was edited in this revision. [diff]

Initialization Code Runtime Reduction Effort

Edited by author.
Last edit: 06:04, 17 February 2013

Here I am going to post information on CPU performance of configuration, construction, drive, gun, and radar. Configuration is one time setting of parameters at beginning of first round. Construction is construction of the scenarios, drives, guns, etc. and loading them into my component chain, also a one time event at beginning of first round. Load stats is loading the previous set of statistics from disk so they can be updated and written back out at the end of the battle. Drive, gun, and radar times are averages and peaks over every tick for the entire battle.

In all I ran averages against 10 seasons.

12.2 is XanderCat 12.2, while 12.3 is the development version of XanderCat 12.3 with whatever CPU performance improvements I can make. Originally I was going to focus on trying to improve initialization, but since turn 0 apparently wasn't getting skipped, I decided to focus on drive and gun improvements instead.

12.2 Normal 12.2 Shielding 12.3 Normal 12.3 Shielding
Opponent Tron Virus Tron Virus
Configure AVG 0.454 0.478 0.459 0.469
Construction AVG 1.304 1.353 1.306 1.310
Load Stats AVG 3.730 3.686 3.690 3.321
Drive AVG 0.478 0.031 0.299 0.016
Drive P1 12.51 5.25 7.34 3.82
Drive P2 11.91 4.70 6.95 3.18
Drive P3 11.46 4.55 6.81 2.99
Gun AVG 0.465 0.153 0.267 0.082
Gun P1 7.12 7.17 5.23 5.84
Gun P2 6.03 5.13 4.44 4.09
Gun P3 5.65 4.26 3.77 2.66
Radar AVG 0.0019 0.0018 0.0018 0.0018
Radar P1 0.10 0.28 0.07 0.35
Radar P2 0.06 0.14 0.05 0.05
Radar P3 0.04 0.04 0.03 0.04
    Skotty22:25, 16 February 2013

    I hadn't thought about it previously, but I can't help but wonder if the loading of battle statistics is one of the bigger problems with skipping turns at the beginning of the first round. On my system, the CPU hit is not all that dramatic, but it could be worse on other systems. Maybe I could defer loading the battle stats until the end of the battle? They are not really needed until the end. How much time does Robocode give at the end of battle for final processing like writing to files?

      Skotty22:30, 16 February 2013
       

      I can think of 2 factors which can mess up skipped turns. Dynamic overclocking and excessive amounts of client instances.

      - Dynamic overclocking changes CPU speed based on load. If the Robocode engine CPU constant is calibrated for an overclocked CPU, then in the beginning of a battle, the reduced clock will provoke skipped turns.

      - Too many client instances make them interfere with each other. Sometimes clients use 2 threads, sometimes only 1. When they use 2 and there isn't any idle core, they steal CPU from another instance and the slower processing speed can provoke skipped turns.

        MN22:49, 16 February 2013
         

        You get extra processing time on ticks that have disk access, but I'm not sure how much.

          Skilgannon22:56, 16 February 2013
           

          Some thoughts...

          • For what it's worth, I tried to generate different CPU constants based on whether it was dynamic overclocking or not, but wasn't able to. Maybe the trigger threshold is well below what a single Robocode instance or the CPU constant calculation uses on my machine.
          • While Robocode does use multiple threads - you might see 50% on two cores or 100% on one core - it only uses 1 at a time, so I'm not sure it's ever really stealing CPU.
          • Since a lot of modern multi-core processors include hyperthreading, there should be some extra buffer such that using 1 Robocode per core is ok.

          To me, the bigger problems are:

          • Measuring CPU time for a single tick in nanoseconds is not nearly as accurate as we need it to be.
          • There's always other system stuff that could use some CPU. Combine with the lack of accuracy and it's really dangerous to penalize for taking too long over a timeframe of just one tick.
            Voidious22:59, 16 February 2013

            Hmm, maybe I'm wrong and System.nanoTime() is accurate enough... [1]

              Voidious23:09, 16 February 2013
               

              I don't know, I agree that dynamic overclocking is theoretically a concern, but from what I can remember, skipped turns have been quirky since long before we all had huge multi-core machines with hyperthreading and dynamic overclocking.

              Quirky like skipping more turns vs an opponent that uses a lot of CPU (but doesn't skip turns!), or skipping lots more turns in the first 50-100 ticks of a battle. Obviously you do some initialization in the first tick, but shouldn't the subsequent ticks be mostly unaffected by that? Seems like that was never the case and still isn't. I guess garbage collection being outside of the scope of Robocode's vision is the most likely culprit for all this. But it's pretty frustrating, in any case.

                Voidious23:36, 16 February 2013

                That's a good point I wasn't even thinking about. Looking at the log Wompi posted again, I can see that all setup was completed on turn 0, and turn 0 wasn't skipped.

                Voidious -- did you check to see if XanderCat appeared to be skipping a lot of turns on your Ubuntu/OJDK machine?

                I can try to improve the CPU performance of my wave surfing drive and guess factor guns, and that might help, but it doesn't really explain the huge number of skipped turns on the first round. In the meantime, if skipped turns is a problem on Voidious' machine, I suppose for now I could just modify my bullet shielding system to try to account for skipped turns.

                  Skotty00:48, 17 February 2013
                   

                  Remembered a 3rd possible cause of skipped turns. The JVM executes all code in interpreted mode for a while until JIT compiler kicks in. And at least in Sun/Oracle JVMs, the default JIT mode, client or server, varies with OS.

                    MN03:58, 17 February 2013
                     

                    Hmm... frustratingly, XanderCat seems to have a higher success rate vs Virus (the most problematic on my system) when running through the UI. I did catch one 56% score with only 2 skipped turns, though, which raises some doubt that skipped turns are the issue (or only issue). Running some more single-threaded seasons with RoboRunner now, in case it's something like a fresh reboot helped (after testing in Windows earlier).

                      Voidious05:15, 17 February 2013
                       

                      I thought once about Robocode being more multi-thread friendly if the engine called Thread.yield() in strategic places, like between ticks. But I never posted this suggestion in sourceforge.

                      This way, most processing outside a Robocode instance would be done between ticks and not interfere with turn skipping.

                      About dynamic overclocking, here I delete config/robocode.properties and run a single instance, which will measure CPU constant at minimum possible speed. Then I copy the file to all other installations. Tried to disable dynamic overclocking as well, but my laptop doesn't have the option in the BIOS.

                        MN23:50, 16 February 2013