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 />

•Thesetwomergedarraysareconcatenatedtogetthef<strong>in</strong>alresult.<br />

In parallelism’s po<strong>in</strong>t of view, two calls of the merge function here are <strong>in</strong>dependent<br />

<strong>and</strong> easy to parallelize. One rough version of parallel MergeSort is sketched as<br />

follows:<br />

let rec pmsort ls =<br />

if Array.length ls pmsort ls1)<br />

let ls2’ =pmsort ls2<br />

pmerge (ls1’.Result, ls2’)<br />

where pmerge is a parallel variant of merge with similar way of parallelization.<br />

The idiom used here is the Future pattern, <strong>and</strong> ls1’ is a future value which will be<br />

executed if its Result property is <strong>in</strong>voked later on. In our example, ls1’.Result<br />

is always executed; therefore, two tasks are always created <strong>and</strong> executed <strong>in</strong> parallel.<br />

To explicitly wait for all tasks to complete, we use Task.WaitAll from<br />

System.Thread<strong>in</strong>g.Tasks module. Here Task.Factory.StartNew creates a task<br />

for runn<strong>in</strong>g computation by wrapp<strong>in</strong>g around a function closure. For example, we<br />

have a similar code fragment as the Future pattern:<br />

let ls1’ =Task.Factory.StartNew(fun () −> pmsort ls1)<br />

let ls2’ =Task.Factory.StartNew(fun () −> pmsort ls2)<br />

Task.WaitAll(ls1’, ls2’)<br />

pmerge (ls1’.Result, ls2’.Result)<br />

Our rough parallel version shows that the CPU usage is better but overall execution<br />

time is not improved compared to the sequential variant. The reason is that<br />

tasks creation is always done regardless of the size of <strong>in</strong>put arrays, which leads to<br />

spawn<strong>in</strong>g too many tasks for just do<strong>in</strong>g trivial jobs. Thus, we <strong>in</strong>troduce one way to<br />

control degree of parallelism:<br />

let rec pmsortUtil (ls, depth) =<br />

if Array.length ls pmsortUtil (ls1, depth−1))<br />

let ls2’ =pmsortUtil (ls2, depth−1)<br />

pmergeUtil (ls1’.Result, ls2’, depth)<br />

let DEPTH =4<br />

let rec pmsort1 ls =<br />

pmsortUtil(ls, DEPTH)<br />

Parallelism is only done until a certa<strong>in</strong> depth. When the size of the array<br />

is rather small, we fall back to the sequential version. Benchmark<strong>in</strong>g done with<br />

different comb<strong>in</strong>ations of depth <strong>and</strong> array size gives us results described <strong>in</strong> Figure<br />

2.3. Detailed source code can be found <strong>in</strong> Appendix A.2.<br />

15

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

Saved successfully!

Ooh no, something went wrong!