Initialization Code Runtime Reduction Effort

Jump to navigation Jump to search
Revision as of 16 February 2013 at 23:48.
The highlighted comment was created in this revision.

Initialization Code Runtime Reduction Effort

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 reductions to initialization by using static initialization blocks and whatever other improvements I can make. I don't have stats for 12.3 yet; hopefully I can edit this post once I have them.

12.2 Normal 12.2 Shielding 12.3 Normal 12.3 Shielding
Opponent Tron Virus Tron Virus
Configure AVG 0.454 0.478
Construction AVG 1.304 1.353
Load Stats AVG 3.730 3.686
Drive AVG 0.478 0.031
Drive P1 12.51 5.25
Drive P2 11.91 4.70
Drive P3 11.46 4.55
Gun AVG 0.465 0.153
Gun P1 7.12 7.17
Gun P2 6.03 5.13
Gun P3 5.65 4.26
Radar AVG 0.0019 0.0018
Radar P1 0.10 0.28
Radar P2 0.06 0.14
Radar P3 0.04 0.04
    Skotty23: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?

      Skotty23: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.

        MN23:49, 16 February 2013
         

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

          Skilgannon23: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.
            Voidious23:59, 16 February 2013

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

              Voidious00:09, 17 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.

                Voidious00:36, 17 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.

                  Skotty01:48, 17 February 2013
                   

                  I thought once about Robocode being more multi-thread friendly if the engine called Thread.yield() in strategy 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.

                    MN00:50, 17 February 2013