Forum Navigation
Strange behaviour in my chameneos test implementation
Posted: 04/29/07 20:08:56 Modified: 04/29/07 21:12:02Hi!
I don't know where to post this problem. And may be this is my error but I don't see it, may be someone could help me.
So, I'm trying to reimplement chameneos benchmark test with Tango. My implementation is presented below. Sometimes it works correctly, but sometimes I get strange results:
bash-3.2$ time ./my_chameneous 40000 creaturesMeet_: 40000 creaturesMeet_: 40000 creaturesMeet_: 40000 creaturesMeet_: 0 creaturesMeet_: 0 80000 real 0m0.281s user 0m0.046s sys 0m0.015s bash-3.2$ time ./my_chameneous 40000 creaturesMeet_: 2579283 creaturesMeet_: 2093332 creaturesMeet_: 2178625 creaturesMeet_: 2290491 9141731 real 0m11.546s user 0m0.031s sys 0m0.016sIn first case must be only four messages 'creaturesMeet_' but there are five. In second case total count of meetings must be 80000, not 9 millions.
May be there are some effects of optiomization and I should use some volatile statements or barriers?
I use DMD v.1.013 and DMD v.1.014, Tango 0.97-RC1, WinXP-SP2. Program was compiled with rebuild 0.18 and command lines:
rebuild -oqo my_chameneous.d rebuild -oqo -O -inline -release my_chameneous.dwith the same effect.
The problem didn't exists with small N and stable at N == 40000 (on my Intel Pentium-M 1.5GHz).
Here is my program:
import tango.core.Thread; import tango.util.locks.Condition; import tango.util.locks.Mutex; import tango.text.convert.Integer; import tango.io.Stdout; typedef int Color; const Color BLUE = 0; const Color RED = 1; const Color YELLOW = 2; const Color FADED = 3; class MeetingPlace { int remaining_ = 10; Mutex lock_; Condition condition_; Color * swappedColor_ = null; this() { lock_ = new Mutex; condition_ = new Condition( lock_ ); } } class Creature : Thread { this( Color my, MeetingPlace meetingPlace ) { super( &run ); my_ = my; meetingPlace_ = meetingPlace; } void run() { while( true ) { Color other = my_; scope localLock = new ScopedLock( meetingPlace_.lock_ ); if( meetingPlace_.remaining_ ) { if( !meetingPlace_.swappedColor_ ) { meetingPlace_.swappedColor_ = &other; meetingPlace_.condition_.wait(); meetingPlace_.swappedColor_ = null; --meetingPlace_.remaining_; } else { other = *meetingPlace_.swappedColor_; *meetingPlace_.swappedColor_ = my_; meetingPlace_.condition_.notify(); } localLock.release; if( FADED != other ) { my_ = complement( other ); ++creaturesMeet_; } } else break; } Stdout( "creaturesMeet_: " )( creaturesMeet_ ).newline; } int total() { return creaturesMeet_; } private : Color my_; MeetingPlace meetingPlace_; int creaturesMeet_ = 0; Color complement( Color other ) { switch( my_ ) { case BLUE: return other == RED ? YELLOW : RED; case RED: return other == BLUE ? YELLOW : BLUE; case YELLOW: return other == BLUE ? RED : BLUE; default: break; } return my_; } } void main( char[][] args ) { auto meetingPlace = new MeetingPlace; if( 2 == args.length ) meetingPlace.remaining_ = parse( args[ 1 ], 10 ); auto colors = [ BLUE, RED, YELLOW, BLUE ]; Creature[] group; foreach( color; colors ) { Creature creature = new Creature( color, meetingPlace ); group ~= creature; creature.start; } int total = 0; foreach( c; group ) { c.join; total += c.total; } Stdout( total ).newline; } // vim:ts=2:sts=2:sw=2:expandtab:fenc=utf-8:Thanks!
Regards, Yauheni Akhotnikau