Overview
Examples
Screenshots
Comparisons
Applications
Download
Documentation
Tutorials
Bazaar
Status & Roadmap
FAQ
Authors & License
Forums
Funding Ultimate++
Search on this site
Search in forums












SourceForge.net Logo
Home » Community » U++ community news and announcements » CoWork::FinLock
CoWork::FinLock [message #45810] Sat, 09 January 2016 20:24 Go to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
Do not ask me why, but recently I was having fun with parallel programming (I looks like it will be unintended addition for the next release... Smile.

In the process, while optimizing everything around CoWork, I got an interesting idea, CoWork::FinLock. It is intended to lock storing partial results into shared target at the end of scheduled routine. The idea is that CoWork has to lock some mutex anyway after the routine ends, so it is possible to 'prelock' this internal mutex and join both critical sections.

Usage looks something like this:

template <typename I, typename Lambda>
void CoLoop(I begin, I end, const Lambda& lambda)
{
	size_t chunk = max(size_t((end - begin) / CPU_Cores()), (size_t)1);
	CoWork co;
	while(begin < end) {
		co & [=] {
			lambda(begin, begin + min(chunk, size_t(end - begin)));
		};
		begin += chunk;
	}
}

template <class I, class Better>
I CoBest(I begin, I end, const Better& better)
{
	I best = begin++;
	CoLoop(begin, end,
		[=, &best](I i, I e) {
			I b = i++;
			while(i < e) {
				if(better(*i, *b))
					b = i;
				i++;
			}
			CoWork::FinLock(); // better is shared across threads, needs a lock!
			if(better(*b, *best))
				best = b;
		}
	);
	return best;
}


(CoBest is intended to lookup e.g. minimum or maximum, 'best' value).
Re: CoWork::FinLock [message #45815 is a reply to message #45810] Sun, 10 January 2016 18:10 Go to previous messageGo to next message
koldo is currently offline  koldo
Messages: 3356
Registered: August 2008
Senior Veteran
Hello Mirek

To help with parallel programming in U++ I have uploaded some benchmarks in new package Bazaar/OpenMP_demp. I hope it will happen as positive NTL vs. STL comparison Smile

About storing partial results, it could be interesting to see demo "Pi" at it uses reduction() clause to handle temporary results between cores.

static double pi_device() {
	double x, y;
	long count = 0, i;
	
	// Parallel loop with reduction for calculating PI  
	#pragma omp parallel for private(i, x, y) shared (samples) reduction(+:count) 
	for (i = 0; i < samples; ++i) {
		x = Random(1000000)/1000000.;
		y = Random(1000000)/1000000.;
		if (sqrt(x*x + y*y) < 1)
			count++;
	}
	return 4.0 * count / samples;
}


Best regards
IƱaki
Re: CoWork::FinLock [message #45816 is a reply to message #45815] Sun, 10 January 2016 22:42 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
koldo wrote on Sun, 10 January 2016 18:10
Hello Mirek

To help with parallel programming in U++ I have uploaded some benchmarks in new package Bazaar/OpenMP_demp. I hope it will happen as positive NTL vs. STL comparison Smile


On this level (I mean reduction demo), it is unlikely - at best the results will be the same.

Mirek
Re: CoWork::FinLock [message #45817 is a reply to message #45816] Sun, 10 January 2016 22:51 Go to previous message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
For the record, here is the implementation with CoLoop listed here:

	int samples = 100000000;
	int count = 0;
	CoLoop(0, samples,
		[=, &count](int a, int b) {
			int lcount = 0;
			while(a < b) {
				double x = Randomf();
				double y = Randomf();
				if(sqrt(x*x + y*y) < 1)
					lcount++;
				a++;
			}
			CoWork::FinLock();
			count += lcount;
		}
	);
Previous Topic: Happy New Year 2016
Next Topic: TheIDE - Python syntax and indention support
Goto Forum:
  


Current Time: Fri Apr 19 13:34:50 CEST 2024

Total time taken to generate the page: 0.02393 seconds