i developed following code:

processSegment[start_, end_] :=
   Module[{segmentVector, segmentNormal},
    segmentVector = end - start;
    segmentNormal = Reverse[segmentVector] {-1, 1} Sqrt[3]/6;
    {Line[{start, start + segmentVector/3}],
     Line[{start + segmentVector/3, 
     start + segmentVector/2 + segmentNormal}],
     Line[{start + segmentVector/2 + segmentNormal, 
     start + 2 segmentVector/3}],
     Line[{start + 2 segmentVector/3, end}]

kochkurve[n_Integer?NonNegative] :=
       Nest[ (#1 /. 
       Line[{start_, finish_}] :> processSegment[start, finish]) &,
              {Line[{{0, 0}, {1, 0}}]},
     AspectRatio -> Automatic, PlotRange -> All]


The matter is, that this code switches the CPU cores very slow (due to the task manager) if ever. So usually one CPU works for about 5 secs the other one do nothing.

Even when i use the integrated Parallelize function there is no change in the workload. Is there any chance to upgrade the workload and if yes, how? And when not, why is that not possible?

  • $\begingroup$ Strongly related: mathematica.stackexchange.com/q/1883/57 $\endgroup$ Jun 9, 2015 at 18:02
  • $\begingroup$ Thank you for the link. But i still have no idea how i could integrate the seperate kernel task into my code. Kernels are not the problem, i have 640 available. So could you give me please a hint how to manage this? $\endgroup$ Jun 11, 2015 at 14:42
  • $\begingroup$ See answer below. $\endgroup$ Jun 11, 2015 at 15:57

1 Answer 1


As you have written it, it is not easily parallelizable. There is just a single task that consists of a Nest. Each iteration in the Nest needs the result of the previous step and that should be available at the start of the next iteration. I don't see how you could parallelize that without a lot of slow inter-process communication.

The best way to parallelize this would be (I think) to let it run until a certain depth (for instance 4 in your case) and let the resulting line elements (256 for n=4) be operated on by 256 separate kernels, which, with your 640 available kernels, shouldn't be a problem.

Changing the code a bit (removing line drawing from processing steps, adding the starting segment as a argument):

ClearAll[kochkurve, processSegment]

kochkurve[n_Integer?NonNegative, {initStart_, initFinish_}] :=
 (Partition[#, 2] &)@(Partition[#, 2] &)@
   Flatten@Nest[(#1 /. {start_, finish_} :> 
         processSegment[start, finish]) &, {{initStart, initFinish}}, n]

processSegment[start_, end_] := Module[{segmentVector, segmentNormal},
  segmentVector = end - start;
  segmentNormal = Reverse[segmentVector] {-1, 1} Sqrt[3]/6;
  {{start, start + segmentVector/3}, {start + segmentVector/3, 
    start + segmentVector/2 + segmentNormal}, {start + 
     segmentVector/2 + segmentNormal, 
    start + 2 segmentVector/3}, {start + 2 segmentVector/3, end}}]

Line /@ ParallelMap[(kochkurve[5, #] &),  kochkurve[4, {{0, 0}, {1, 0}}]] // Graphics

enter image description here

Tasks could be launched by ParallelSubmit and started with WaitAll as well.

Line /@ WaitAll[ParallelSubmit[(kochkurve[5, #])] & /@ 
      kochkurve[4, {{0, 0}, {1, 0}}]] // Graphics

Most mortals probably want the rightmost kochkurve to be only 1 level deep (4 segments and hence 4 kernels).

  • $\begingroup$ Thats just awesome. Thank you. This nearly halves the the calculation time. $\endgroup$ Jun 11, 2015 at 16:42
  • $\begingroup$ With so many kernels available to you that's a bit disappointing, though I get only a 25% improvement. It may help to play with the balance between the first and second kochkurve contribution. I find it helps if the rightmost kochkurve yields somewhat more initial pieces than kernels. $\endgroup$ Jun 11, 2015 at 17:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.