29.04.2014 Views

Presburger Arithmetic and Its Use in Verification

Presburger Arithmetic and Its Use in Verification

Presburger Arithmetic and Its Use in Verification

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

2.2. MULTICORE PARALLELISM ON .NET FRAMEWORK<br />

allows users to write queries <strong>in</strong> a very declarative style which does not expose any<br />

side effect <strong>and</strong> shows nature of problems very clearly:<br />

let NUM_STEPS =100000000<br />

let steps =1.0/(float NUM_STEPS)<br />

let sqr x = x ∗ x<br />

let l<strong>in</strong>qCompute1() =<br />

(Enumerable<br />

.Range(0, NUM_STEPS)<br />

.Select(fun i −> 4.0/(1.0+sqr((float i +0.5)∗steps)))<br />

.Sum()<br />

)∗steps<br />

Computation is done <strong>in</strong> three steps. First, the range of 100,000,000 elements are<br />

constructed as an <strong>in</strong>stance of Enumerable class, <strong>and</strong> this type is a central element for<br />

accommodat<strong>in</strong>g LINQ queries. Second, the Select method calculates <strong>in</strong>termediate<br />

values for all <strong>in</strong>dices. F<strong>in</strong>ally, the Sum function aggregates all immediate results.<br />

Due to the advantage of side effect free, LINQ queries are easy to parallelize. In<br />

reality, .NET platform has supported LINQ queries <strong>in</strong> a parallel manner by PLINQ<br />

constructs. The calculation π is turned <strong>in</strong>to parallel execution by just chang<strong>in</strong>g<br />

Enumerable to ParallelEnumerable to <strong>in</strong>dicate usage of PLINQ:<br />

let pl<strong>in</strong>qCompute2() =<br />

(ParallelEnumerable<br />

.Range(0, NUM_STEPS)<br />

.Select(fun i −> 4.0/(1.0+sqr((float i +0.5)∗steps)))<br />

.Sum()<br />

)∗steps<br />

PLINQ provides users a cheap way to do parallelization <strong>in</strong> .NET framework; our<br />

PLINQ version is 3-4× faster than the LINQ companion. One question raised is:<br />

why not provide PLINQ as a default option for data query<strong>in</strong>g <strong>in</strong> .NET. The reason<br />

is that PLINQ is not always faster than its correspond<strong>in</strong>g LINQ companion. To be<br />

worth us<strong>in</strong>g PLINQ, a task should be big <strong>and</strong> conta<strong>in</strong> rather <strong>in</strong>dependent subtasks.<br />

Certa<strong>in</strong>ly, parallel process<strong>in</strong>g by us<strong>in</strong>g PLINQ has drawbacks of little control over<br />

degree of parallelism <strong>and</strong> the way tasks are split <strong>and</strong> distributed over process<strong>in</strong>g<br />

units.<br />

Our third version is a simple for loop runn<strong>in</strong>g 100,000,000 times <strong>and</strong> gradually<br />

gather<strong>in</strong>g results implemented by means of recursion <strong>in</strong> F#:<br />

let compute3() =<br />

let rec computeUtil(i, acc) =<br />

if i =0then acc ∗ steps<br />

else<br />

let x =(float i +0.5)∗steps<br />

computeUtil (i−1, acc +4.0/(1.0+x ∗ x))<br />

computeUtil(NUM_STEPS, 0.0)<br />

<strong>Its</strong> parallel equivalent is written us<strong>in</strong>g Parallel.For construct:<br />

11

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!