Note that there are some explanatory texts on larger screens.

plurals
  1. POIs there any "threshold" justifying multithreaded computation?
    primarykey
    data
    text
    <p>So basically I needed to optimize this piece of code today. It tries to find the longest sequence produced by some function for the first million starting numbers:</p> <pre><code>public static void main(String[] args) { int mostLen = 0; int mostInt = 0; long currTime = System.currentTimeMillis(); for(int j=2; j&lt;=1000000; j++) { long i = j; int len = 0; while((i=next(i)) != 1) { len++; } if(len &gt; mostLen) { mostLen = len; mostInt = j; } } System.out.println(System.currentTimeMillis() - currTime); System.out.println("Most len is " + mostLen + " for " + mostInt); } static long next(long i) { if(i%2==0) { return i/2; } else { return i*3+1; } } </code></pre> <p>My mistake was to try to introduce multithreading:</p> <pre><code>void doSearch() throws ExecutionException, InterruptedException { final int numProc = Runtime.getRuntime().availableProcessors(); System.out.println("numProc = " + numProc); ExecutorService executor = Executors.newFixedThreadPool(numProc); long currTime = System.currentTimeMillis(); List&lt;Future&lt;ValueBean&gt;&gt; list = new ArrayList&lt;Future&lt;ValueBean&gt;&gt;(); for (int j = 2; j &lt;= 1000000; j++) { MyCallable&lt;ValueBean&gt; worker = new MyCallable&lt;ValueBean&gt;(); worker.setBean(new ValueBean(j, 0)); Future&lt;ValueBean&gt; f = executor.submit(worker); list.add(f); } System.out.println(System.currentTimeMillis() - currTime); int mostLen = 0; int mostInt = 0; for (Future&lt;ValueBean&gt; f : list) { final int len = f.get().getLen(); if (len &gt; mostLen) { mostLen = len; mostInt = f.get().getNum(); } } executor.shutdown(); System.out.println(System.currentTimeMillis() - currTime); System.out.println("Most len is " + mostLen + " for " + mostInt); } public class MyCallable&lt;T&gt; implements Callable&lt;ValueBean&gt; { public ValueBean bean; public void setBean(ValueBean bean) { this.bean = bean; } public ValueBean call() throws Exception { long i = bean.getNum(); int len = 0; while ((i = next(i)) != 1) { len++; } return new ValueBean(bean.getNum(), len); } } public class ValueBean { int num; int len; public ValueBean(int num, int len) { this.num = num; this.len = len; } public int getNum() { return num; } public int getLen() { return len; } } long next(long i) { if (i % 2 == 0) { return i / 2; } else { return i * 3 + 1; } } </code></pre> <p>Unfortunately, the multithreaded version worked 5 times slower than the single-threaded on 4 processors (cores).</p> <p>Then I tried a bit more crude approach:</p> <pre><code>static int mostLen = 0; static int mostInt = 0; synchronized static void updateIfMore(int len, int intgr) { if (len &gt; mostLen) { mostLen = len; mostInt = intgr; } } public static void main(String[] args) throws InterruptedException { long currTime = System.currentTimeMillis(); final int numProc = Runtime.getRuntime().availableProcessors(); System.out.println("numProc = " + numProc); ExecutorService executor = Executors.newFixedThreadPool(numProc); for (int i = 2; i &lt;= 1000000; i++) { final int j = i; executor.execute(new Runnable() { public void run() { long l = j; int len = 0; while ((l = next(l)) != 1) { len++; } updateIfMore(len, j); } }); } executor.shutdown(); executor.awaitTermination(30, TimeUnit.SECONDS); System.out.println(System.currentTimeMillis() - currTime); System.out.println("Most len is " + mostLen + " for " + mostInt); } static long next(long i) { if (i % 2 == 0) { return i / 2; } else { return i * 3 + 1; } } </code></pre> <p>and it worked much faster, but still it was slower than the single thread approach.</p> <p>I hope it's not because I screwed up the way I'm doing multithreading, but rather this particular calculation/algorithm is not a good fit for parallel computation. If I change calculation to make it more processor intensive by replacing method <code>next</code> with:</p> <pre><code>long next(long i) { Random r = new Random(); for(int j=0; j&lt;10; j++) { r.nextLong(); } if (i % 2 == 0) { return i / 2; } else { return i * 3 + 1; } } </code></pre> <p>both multithreaded versions start to execute more than twice as fast than the singlethreaded version on a 4 core machine.</p> <p>So clearly there must be some threshold that you can use to determine if it is worth to introduce multithreading and my question is: </p> <p><em>What is the basic rule that would help decide if a given calculation is intensive enough to be optimized by running it in parallel (without spending effort to actually implement it?)</em></p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload