# Threads vs Cores: How many kernels need to launch in parallel Mathematica?

I have a dual-core intel machine. I would like to test how many parallel local kernels should be launch to get the optimized performance. Knowing that the HyperThreading technology of Intel could run 2 "Threads" on 1 core. That means we could run 4 threads on a dual-core CPU. For informations about "Threads vs Cores", look at here.. AMD says "no" to HyperThreading, and after them, cores is much more important. view amd vs intel: "Based on the results of the Cinebench® and PovRay® benchmark tests, we find that physical cores outperform enhanced threading software in certain applications."

Function to evaluate:

mlength[z_] :=
Length[FixedPointList[#^2 + z &, z, 20, SameTest -> (Abs[#] > 2 &)]]


1. Sequential Evaluation (No parallel)

CloseKernels[]; Kernels[]
ParallelTable[
mlength[x + I y], {y, -1, 1, 0.005}, {x, -2, 1,
0.005}]; // AbsoluteTiming


During evaluation of ParallelTable::nopar: No parallel kernels available; proceeding with sequential evaluation.

{8.814056, Null}

Although no parallel kernel is used, we can see that the second core on the right shares about 50% the work with the first core. I think Windows automatically shares the work for multicore.

2. Using 1 Slave kernel

CloseKernels[]; LaunchKernels[1]; Kernels[]
ParallelTable[
mlength[x + I y], {y, -1, 1, 0.005}, {x, -2, 1,
0.005}]; // AbsoluteTiming


{9.110458, Null}

By asking Mathematica add one slave kernel, this slave kernel runs on the first core mainly (on the left) and we can see that the work is mainly done in the first core. There are still some works on the second core.

3. Using 2 slaves kernel

CloseKernels[]; LaunchKernels[2]; Kernels[]
ParallelTable[
mlength[x + I y], {y, -1, 1, 0.005}, {x, -2, 1,
0.005}]; // AbsoluteTiming


{4.820431, Null}

Now, with 2 slaves kernels, the work is evenly distributed on 2 cores. That's the reason why, we get the results done in half of the time. We can see that Mathematica parallelizes better than Windows.

4.Using 4 slaves kernel

CloseKernels[]; LaunchKernels[4]; Kernels[]
ParallelTable[
mlength[x + I y], {y, -1, 1, 0.005}, {x, -2, 1,
0.005}]; // AbsoluteTiming


{5.023232, Null}

I'm trying to add more kernels by supposing that, one core could maintain 2 "threads". But the results is slower. I think Multithreading does not help in Mathematica. So the rule of thumb is: the number of parallel local kernels = number of cores (not threads). Increasing number of kernel just increases the overhead of data transfer between kernels.

Any suggestions?

=================================================================

Udate to another computer Intel i7, 4 CORES, 8 THREADS (TRUE HT).

maxKernel = 8;
data = Table[
CloseKernels[];
LaunchKernels[n];
ParallelTable[
mlength[x + I y], {y, -2, 1, 0.002}, {x, -2, 1, 0.002}]; //
AbsoluteTiming // First, {n, 0, maxKernel}]


{40.332307, 44.634553, 22.154267, 17.925025, 14.795846, 13.280760, \ 12.369708, 13.218756, 12.701726}

We can see that, the time decreases up to 4 Cores, and then, up to 6 threads, time optimized only 1-2 second.

• HT is not a solution when your task is mostly compute-intensive, and most M tasks, especially when done in parallel, are done for compute purposes. When two threads run over the same core, they still share the same ALU, load/store units, etc. HT is great when you have to handle a lot of objects, for example for webservers, where you handle a lot of connection objects, request objects, etc. But for compute-intensive applications, HT gives you only a very small improvement, namely to the extent that the parallel threads don't use the same ALU -- and there is very little of that. Dec 17 '13 at 17:18
• For compute-intensive tasks, every thread needs its own ALU, and HT doesn't give you that. You have turned 4 physical cores into 8 virtual cores, but you haven't doubled the number of ALUs. You're almost back at square 1. I have done a lot of this type of benchmarking, and in my own comparisons turning HT on improved execution times 5 - 10% compared to the runs when I had turned HT off. Dec 17 '13 at 17:20
• @AndreasLauschke SMT (a.k.a. HT) is very good for hiding cache miss latency (this being actually its main reason for existing). For applications with large, poorly localized working sets, such as symbolic calculations in Mathematica, SMT should be quite helpful. Its efficacy does of course depend on the specific calculation being attempted. Dec 18 '13 at 2:43
• Re: "Windows automatically shares the work for multicore" -- not quite. To improve scheduling fairness, some versions of Windows move the running thread around between processors. The rate at which it does this is so fast as not to be observable on the performance graph, so it looks like the work is being shared, when actually it is just alternating between one processor and the other. Newer versions of Windows try to keep running threads on a single processor since moving them around unnecessarily can possibly result in poisoning the cache. Dec 18 '13 at 2:58
• @OleksandrR."such as symbolic calculations in Mathematica, SMT should be quite helpful." -- yes, this is what I have included under "objects". Symbolic calculations in M are based on pattern matching, more specifically, term-rewriting. That is the foundation of M's symbolic engine, at the very core M is a term-rewriting system. But this is not what I was referring to when I mentioned "compute-intensive". No doubt that symbolic calculations benefit from HT. But those are not computations. HT does nothing when it comes to computations. Symbolic manipulations, yes, absolutely. Dec 18 '13 at 5:45