Difference between revisions of "Threads and Executors"

From CSE231 Wiki
Jump to navigation Jump to search
Line 1: Line 1:
 
This assignment has been updated: [[Thread_and_Executor_Service_Assignment|Thread and ExecutorService]]
 
This assignment has been updated: [[Thread_and_Executor_Service_Assignment|Thread and ExecutorService]]
 
+
<!--
 
credit for this assignment: [[User:Finn|Finn Voichick]] and [[User:cosgroved|Dennis Cosgrove]]
 
credit for this assignment: [[User:Finn|Finn Voichick]] and [[User:cosgroved|Dennis Cosgrove]]
 
=Motivation=
 
=Motivation=
Line 109: Line 109:
  
 
As always, the [[Reference_Page#Executors|wiki's reference page]] can be of help.
 
As always, the [[Reference_Page#Executors|wiki's reference page]] can be of help.
 
<!--
 
  
 
===Mistake To Avoid: Do NOT call shutdown===
 
===Mistake To Avoid: Do NOT call shutdown===
 
Each method you write will be passed an executor.  You need not (and should NOT) invoke [https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html#shutdown-- shutdown()].  That is the responsibility of whoever created the executor.  For example, a JUnit test would do this if it was appropriate (i.e. it created an executor and was not using the [https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ForkJoinPool.html#commonPool-- common pool]).
 
Each method you write will be passed an executor.  You need not (and should NOT) invoke [https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html#shutdown-- shutdown()].  That is the responsibility of whoever created the executor.  For example, a JUnit test would do this if it was appropriate (i.e. it created an executor and was not using the [https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ForkJoinPool.html#commonPool-- common pool]).
-->
 
  
 
===XNucleobaseCount===
 
===XNucleobaseCount===
Line 162: Line 159:
 
{{Warning|Unlike in Sarkar's and McDowell’s videos which use inclusive maximums, CSE 231 consistently uses exclusive maximums to avoid having to subtract 1 all of the time.}}
 
{{Warning|Unlike in Sarkar's and McDowell’s videos which use inclusive maximums, CSE 231 consistently uses exclusive maximums to avoid having to subtract 1 all of the time.}}
  
<!--
 
====The Core Questions====
 
*What are the tasks?
 
*What is the data?
 
*Is the data mutable?
 
*If so, how is it shared?
 
-->
 
 
====Code To Use====
 
====Code To Use====
 
[https://www.cse.wustl.edu/~cosgroved/courses/cse231/current/apidocs/sort/core/quick/Partitioner.html interface Partitioner]
 
[https://www.cse.wustl.edu/~cosgroved/courses/cse231/current/apidocs/sort/core/quick/Partitioner.html interface Partitioner]

Revision as of 19:39, 22 February 2022

This assignment has been updated: Thread and ExecutorService

Code To Use

interface ExecutorService

submit(task)
invokeAll(tasks)

interface Future

get()

NucleobaseCounting

countRangeSequential(chromosome,targetNucleobase,min,maxExclusive)

Slices

createNSlices(data, numSlices).


As always, the wiki's reference page can be of help.

Mistake To Avoid: Do NOT call shutdown

Each method you write will be passed an executor. You need not (and should NOT) invoke shutdown(). That is the responsibility of whoever created the executor. For example, a JUnit test would do this if it was appropriate (i.e. it created an executor and was not using the common pool).

XNucleobaseCount

This part of the assignment should be very familiar as it is to a large degree implementing the Nucleobase Counting assignment with Executors instead of Habanero. It also adds a divide and conquer implementation of nucleobase counting.

class: XNucleobaseCount.java Java.png
methods: countLowerUpperSplit
countNWaySplit
countDivideAndConquer
countDivideAndConquerKernel
package: tnx.lab.executor
source folder: student/src/main/java
Circle-information.svg Tip:Use countRangeSequential() from Nucleobase_Counting

lower upper split

method: int countLowerUpperSplit(ExecutorService executor, byte[] chromosome, Nucleobase nucleobase) Parallel.svg (parallel implementation required)

NOTE: the tests will enforce that you use submit and get.

n-way split

method: int countNWaySplit(ExecutorService executor, byte[] chromosome, Nucleobase nucleobase, int numTasks) Parallel.svg (parallel implementation required)

Please feel free to use your own Slices createNSlices(byte[] data, int numSlices). Then use the Java for each loop to iterate over the slices to create your tasks.

NOTE: the tests will enforce that you use invokeAll.

divide-and-conquer

method: int countDivideAndConquer(ExecutorService executor, byte[] chromosome, Nucleobase nucleobase, int threshold) Parallel.svg (parallel implementation required)

This method should just get things going by invoking the countDivideAndConquerKernel on the entire chromosome array.

method: int countDivideAndConquerKernel(ExecutorService executor, byte[] chromosome, Nucleobase nucleobase, int min, int maxExclusive, int threshold) Parallel.svg (parallel implementation required)

NOTE: the tests will enforce that you use submit and get.


NOTE: When you get down below the threshold and convert from parallel to sequential execution, do NOT feel compelled to build a sequential divide and conquer. Just invoke countRangeSequential on the remaining range. It is not like divide and conquer gives you a performance benefit in counting like it would for sorting.

XQuicksort

Quicksort is an oldie but a goodie. First developed in 1959 and published in 1961 it is still the go to sorting algorithm today. The JDK8 implementation of Arrays.sort(array) is a DualPivotQuicksort.

Quicksort is also amenable to parallelism. Once the partitioning is done, both sides of the pivot can be sorted completely independently in parallel. This lends itself very nicely to the X10 family of languages as you can freely async as you divide and conquer, then join all of the tasks by wrapping it all in a single call to finish.

In this assignment you will mimic this behavior by submitting tasks to an executor, tracking the returned futures in in a ConcurrentLinkedQueue, then invoking get on all of those futures to mimic the single finish.

Attention niels epting.svg Warning: ConcurrentLinkQueue's iterators are weakly consistent. Do the Join All Warm Up to gain experience with handling this issue.

RiceX Lecture on Quicksort

Attention niels epting.svg Warning:Unlike in Sarkar's and McDowell’s videos which use inclusive maximums, CSE 231 consistently uses exclusive maximums to avoid having to subtract 1 all of the time.

Code To Use

interface Partitioner

partitionRange(data,min,maxExclusive)

class PivotLocation

getLeftSidesUpperExclusive()
getRightSidesLowerInclusive()

Note: Investigate SequentialPartitioner.

XSequentialQuicksorter

class: XSequentialQuicksorter.java Java.png
methods: sortRange
package: tnx.lab.executor
source folder: student/src/main/java

method: public void sortRange(T[] data, Comparator<T> comparator, int min, int maxExclusive) Sequential.svg (sequential implementation only)

Attention niels epting.svg Warning:Do NOT implement your own partition. Call Partitioner partitionRange method. It will do this work for you.
Attention niels epting.svg Warning:Do NOT invoke partitionRange twice. Invoke partitionRange once and catch the return value in a variable. Then use the two methods on the single instance of PivotLocation.

XParallelQuicksorter

class: XParallelQuicksorter.java Java.png
methods: kernel
sortRange
package: tnx.lab.executor
source folder: student/src/main/java

method: private void kernel(Queue<Future<?>> futures, T[] data, Comparator<T> comparator, int min, int maxExclusive) Parallel.svg (parallel implementation required)

Circle-information.svg Tip: Be sure to test the isParallelPredicate to determine if the current range length is worthy of parallel processing or if you should fall back to the sequentialSorter.

method: public void sortRange(T[] data, Comparator<T> comparator, int min, int maxExclusive) Sequential.svg (sequential implementation only)

Circle-information.svg Tip: Make sure to use a thread safe data structure like ConcurrentLinkedQueue and NOT an unsafe data structure like LinkedList.
Circle-information.svg Tip: return null; from your lambdas to invoke the overloaded Callable version of submit(task) to deal with the checked exceptions.
Attention niels epting.svg Warning:Do NOT implement your own partition. Call Partitioner partitionRange method. It will do this work for you.
Attention niels epting.svg Warning:Do NOT invoke partitionRange twice. Invoke partitionRange once and catch the return value in a variable. Then use the two methods on the single instance of PivotLocation.

(Optional) Parallel Partition Challenge

The partitioning step can also be done in parallel with scan. While not particularly practical, it can get the CPL down to .

For details on how to complete this challenge, check out: Quicksort_Parallel_Partitioner

Testing Your Solution

Correctness

There is a top-level test suite comprised of sub test suites which can be invoked separately when you want to focus on one part of the assignment.

top level

class: ThreadsAndExecutorsTestSuite.java Junit.png
package: tnx.lab
source folder: testing/src/test/java

sub

class: ThreadsTestSuite.java Junit.png
package: tnx.lab.thread
source folder: testing/src/test/java
class: NucleobaseExecutorTestSuite.java Junit.png
package: tnx.lab.executor
source folder: testing/src/test/java
class: QuicksortExecutorTestSuite.java Junit.png
package: tnx.lab.executor
source folder: testing/src/test/java

Less Time Consuming Suite

class: QuicksortExecutorNonWeaklyConsistentIteratorTestSuite.java Junit.png
package: tnx.lab.executor
source folder: testing/src/test/java

Performance

class: NucleobaseCountTiming.java Noun Project stopwatch icon 386232 cc.svg
package: tnx.lab.executor
source folder: src/main/java
class: QuicksortTiming.java Noun Project stopwatch icon 386232 cc.svg
package: tnx.lab.executor
source folder: src/main/java


Rubric

As always, please make sure to cite your work appropriately.

Total points: 100

SimpleThreadFactory subtotal: 5

  • Correct newThread (5)

TAgeSum subtotal: 10

  • Correct sumUpperLowerSplit (10)

XNucleobaseCount subtotal: 40

  • Correct count2WaySplit (10)
  • Correct countNWaySplit (15)
  • Correct countDivideAndConquer and countDivideAndConquerKernel (15)

XQuicksort subtotal: 35

  • Correct sequentialQuicksort and sequentialQuicksortKernel (10)
  • Correct parallelQuicksort and parallelQuicksortKernel (25)

Whole project:

  • Clarity and efficiency (10)

Pledge, Acknowledgments, Citations

file: lab-threads-and-executors-pledge-acknowledgments-citations.txt

More info about the Honor Pledge -->