Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I'm trying to use a LibraryLink function in parallel. It is an embarrassingly parallel problem, so that no dependency between those parallel tasks. However I can only get the parallel efficiency about 0.68. So is it possible to increase this parallel efficiency, or that is just the best I can expect from Mathematica?

Here is a simplified example and some benchmark of the performance. The test was performed in version 9 for linux on Red Hat Enterprise Linux 6, on a computer node with 16 cores (two 8-Core Sandy Bridge Xeon E5-2670 64-bit processors).

Define of the library function

lf = Compile[{{n, _Real}}, 
  Sum[Sin[Sin[Exp[I x]]]^2, {x, 0., 1000 n, 0.1}], 
  CompilationTarget -> "C"];

lf[10] // AbsoluteTiming
(*{0.028269, 2.3085 + 0.363265 I}*)

LCM[2, 4, 6, 8, 10, 12, 14, 16]
(*1680*)

Test the performance using different parallel methods

single evaluation time 0.028 second

lf[10] // AbsoluteTiming
(*{0.028207, 2.3085 + 0.363265 I}*)

tSerial = AbsoluteTiming[Sum[lf[10], {x, 1, 1680}]][[1]]
(*47.253332*)

Method->"FinestGrained"

speedupIdeal = Table[{n, n}, {n, 2, 16, 2}];
timeIdeal = Table[tSerial/n, {n, 2, 16, 2}];
timeFG = Table[
  CloseKernels[]; LaunchKernels[n]; DistributeDefinitions[lf];
  {n, AbsoluteTiming[
     ParallelSum[lf[10], {x, 1, 1680}, Method -> "FinestGrained"]][[1]]},
  {n, 2, 16, 2}]
(*{{2, 27.148232}, {4, 14.178885}, {6, 9.885146}, {8, 7.751356}, {10, 
  6.633211}, {12, 5.887295}, {14, 4.141049}, {16, 3.978317}}*)

Method->"EvaluationsPerKernel"->1

time1perK = Table[
  CloseKernels[]; LaunchKernels[n]; DistributeDefinitions[lf];
  {n, AbsoluteTiming[
     ParallelSum[lf[10], {x, 1, 1680}, 
      Method -> "EvaluationsPerKernel" -> 1]][[1]]},
  {n, 2, 16, 2}]
(*{{2, 24.009900}, {4, 12.616673}, {6, 8.320600}, {8, 6.372430}, {10, 
  5.095200}, {12, 4.477966}, {14, 4.131756}, {16, 3.680885}}*)

Method->"CoarsestGrained"

timeCG = Table[
  CloseKernels[]; LaunchKernels[n]; DistributeDefinitions[lf];
  {n, AbsoluteTiming[
     ParallelSum[lf[10], {x, 1, 1680}, Method -> "CoarsestGrained"]][[1]]},
  {n, 2, 16, 2}]    
(*{{2, 23.918878}, {4, 13.041166}, {6, 8.958082}, {8, 6.629995}, {10, 
  5.615827}, {12, 4.408525}, {14, 4.123634}, {16, 3.507930}}*)

compare speedup

ListPlot[{
  speedupIdeal,
  timeFG /. {x_, y_} -> {x, tSerial/y},
  time1perK /. {x_, y_} -> {x, tSerial/y},
  timeCG /. {x_, y_} -> {x, tSerial/y}
  }, PlotRange -> All, Joined -> True, Mesh -> All, Axes -> False, 
 Frame -> True, FrameLabel -> {"number of kernel", "speedup"}, 
 FrameStyle -> Large, 
 PlotLegends -> 
  LineLegend[{"ideal", "FinestGrained", "EvaluationsPerKernel\[Rule]1", 
    "CoarsestGrained"}]]

enter image description here


Update

In order to test whether this slow down comes from the LibraryLink or just the parallel mechanism, here are two tests. The first one using a function that only compiled to the virtual machine, the second one without compile.

Compile to VM

The same as above, just change

lf = Compile[{{n, _Real}}, 
  Sum[Sin[Sin[Exp[I x]]]^2, {x, 0., 1000 n, 0.1}]]

enter image description here

No compile

The same as above, but change

lf = Function[{n}, Sum[Sin[Sin[Exp[I x]]]^2, {x, 0., 1000 n, 0.1}]]

and also all lf[10] were changed to lf[1] to account for the slowness of uncompiled function.

enter image description here

share|improve this question

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.