Using Java multithreading, what is the most efficient to coordinate finding the best result? -


let me clear, method describe below operational. i'm hoping improve throughput of method. works, , works quite well. we're looking scale throughput more why i'm looking this.

the task @ hand improve performance of scoring algorithm returns best score collection of tasks. have collection of tasks perform scoring on using executorservice. each task checks see if has best score, , updates best score in synchronized fashion if new best. give insight scale i'm working at, each task takes fraction of millisecond complete, there thousands of them, resulting in several hundred milliseconds find best one. execute scoring algorithm several hundred times minute. result 30 second out of 60 spent running scoring algorithm.

when thread pool 8 threads (with 24 virtual cores), tasks take 0.3 ms each. when have 20 threads (same machine, 24 virtual cores) tasks take 0.6 ms each. suspect add more threads executorservice thread pool performance getting worse because of synchronization on best score (more threads contending lock).

i have done quite bit of searching, can't seem find satisfactory (actually, can't seem find any) alternatives. i'm thinking collecting scores , either storing in sorted order, or sorting after tasks completed--but i'm unsure if improvement.

does have thoughts of another, more efficient way of collecting best score?

here's current methodology:

final double[] bestscore = { double.max_value }; // each item in collection {     tasks.add(executors.callable(new runnable() {         public void run() {             double score = //... scoring task             if (score < bestscore[0]) {                 synchronized(bestscore) {                     if (score < bestscore[0]) { // check again after have lock                         bestscore[0] = score;                         ...                         // save off other task identifiers in similar fashion                     }                 }             }         }     } } // end of loop creating scoring tasks  list<future<object>> futures = executorservice.invokeall(tasks /*...timeout params here*/); ... // handle cancelled tasks   // use best scoring task saved off when found. 

i'll have take granted fact want compute each individual score separate task submitted executorservice. there must other benefits, otherwise overhead isn't worth it. normally, you'd implement callable returns score (or object score , other pertinent results) when executed. after successful invocation of tasks, results examined in main thread obtain best.

given constraints, however, 1 optimization try using doubleaccumulator, intended cases these, instead of one-element array , synchronization. this:

final doubleaccumulator lowest = new doubleaccumulator(math::min, double.positive_infinity); /* loop, creating tasks... */ ( ... ) {   tasks.add(executors.callable(new runnable() {     public void run()     {       double score = 0; /* compute real score here. */       lowest.accumulate(score);     }   })); } /* invoke tasks, when successful... */ double lowestscore = lowest.get(); 

if need track information besides score, can similar atomicreference, creating data object carries task identifier, score, , other needed properties, , using 1 of its accumulators.

if tasks initialized sort of recursive, divide-and-conquer approach, resulting in non-blocking, equally-sized tasks, fork-join framework underlying parallel stream might fit too.

again, though, point out if more threads decreased performance, measuring use of fewer threads seems prudent.


Comments

Popular posts from this blog

c++ - Difference between pre and post decrement in recursive function argument -

c# - Retrieve google contact -

javascript - How to insert selected radio button value into table cell -