void test_distributed_mutexes(redis::client & c) { redis::distributed_int dist_int(INT_VARIABLE, c); dist_int = 0; ASSERT_EQUAL(dist_int.to_int(), 0); ostringstream os; os << "incremented in " << THREAD_COUNT << " threads with distributed mutexes"; { block_duration dur(os.str(), THREAD_COUNT*INCREM_COUNT); boost::array< boost::optional<unsave_increment_in_mutex>, THREAD_COUNT > incrementors; boost::array< boost::thread, THREAD_COUNT > threads; for(int i=0; i < THREAD_COUNT; i++) incrementors[i] = unsave_increment_in_mutex(c, "mutex1", INCREM_COUNT); for(int i=0; i < THREAD_COUNT; i++) threads[i] = boost::thread( *incrementors[i] ); for(int i=0; i < THREAD_COUNT; i++) threads[i].join(); } ASSERT_EQUAL( boost::lexical_cast<int>( c.get(INT_VARIABLE) ), THREAD_COUNT*INCREM_COUNT); ASSERT_EQUAL(dist_int.to_int(), THREAD_COUNT*INCREM_COUNT); }
void operator()() { redis::distributed_int dist_int(INT_VARIABLE, 0, *shr_c); for(int i=0; i < count; i++) { redis::distributed_mutex::scoped_lock lock(mutex); redis::client::int_type local_int = dist_int.to_int() + 1; dist_int = local_int; if( local_int % (THREAD_COUNT*10-1) == 0 ) { //cout << boost::this_thread::get_id() << ": " << local_int << endl; } } ASSERT_EQUAL(dist_int.to_int() >= count, true); }
int main() { const unsigned oversample = 2; const unsigned w = 2048*oversample, h = 2048*oversample; cout << "allocating memory for a " << w << " x " << h << " image buffer..." << flush; simg img( w, h, {0, 0, 0, 255} ); cout << " done." << endl; // list of points const int numpoints = 5; uniform_int_distribution<> dist_int( 0, numpoints-1 ); vector< double[2] > points( numpoints ); // radius: 0.5 will just touch the edges of the image const double rad = 0.99 * 0.5; // initial rotation: not important but makes each image unique const double rot = rand01(); // distribute points evenly around a circle (not necessary, but makes it easy to compare) for( int p = 0; p < numpoints; p++ ) { double angle = (rot + ((double)p / numpoints)) * 2. * 3.14159265358979323846; points[p][0] = 0.5 + rad*cos(angle); points[p][1] = 0.5 + rad*sin(angle); } // additive RGBA (may be negative, usually want to leave alpha = 0) const srgba_light light = {10, 10, 10, 0}; // a touchy constant: too big and the render appears fuzzy const double beta = 1. / 2.; // note: may need to try many different starting points to get a good image // * note: so far has worked with a single starting point double point[2] = { rand01(), rand01() }; // how many times to plot the point: too big = slow const unsigned long numplots = 100000000; // do a render cout << "rendering " << numplots << " points..." << flush; for( unsigned long i = 0; i < numplots; i++ ) { // pick a point to move toward int p = dist_int( rand_gen ); // compute new coordinates point[0] = points[p][0] + beta * ( point[0] - points[p][0] ); point[1] = points[p][1] + beta * ( point[1] - points[p][1] ); // plot point if( point[0] >= 0. && point[0] < 1. && point[1] >= 0. && point[1] < 1. ) { unsigned x = floor(point[0] * w); unsigned y = floor(point[1] * h); img.add( x, y, light ); } } cout << " done." << endl; char filename[1024]; sprintf( filename, "%d-points_%ux%u_%lu-samples.png", numpoints, w, h, numplots ); img.save( string(filename) ); return 0; }