syzygy wrote:JuLieN wrote:And the CPU monitor shows the task using only 113% of the CPU (when, if optimal, it should use 800%).
So you're either spawning and destroying threads for each invocation of your move generator, or you're waking up and pausing threads. With such super tiny batches of work, this will indeed kill performance.
Your results would probably have been less bad if you had used spinlocks for synchronisation. Still, with such tiny batches of work it makes little sense to try to get it to work.
Yes, I used
a simple extension unit of the Object Pascal, mtprocs, that does just that: creating threads and destroying them when the task is done. It allows to create multithreaded applications with very little code modification, but it's (much) less efficient than creating a multithreaded app from the ground up. As they say in the doc, it is only interesting if the tasks last for at least a few milliseconds, which is of course not the case when creating the list of legal moves for a given position. Take my 22 millions MPS monothread engine: with an average of, say, 35 legal moves per position, it gives 628,000 such lists created every second, or one every 0.00159 seconds (so, every 0.00159 millisecond).
But for any task that takes at least a few ms, this unit is indeed very interesting for the lazy programmer.
Joerg Oster wrote:And how about splitting the eval? Will you try this, too?
Unfortunately, I'm still a beginner in programming (though 47 years of age

), and this is way beyond my poor skills.
I won't, Joerg, sorry. I see no reason why I would get better results with the eval function. Typically my engine rates 1.2 millions positions per second during a game, so you can make the same computation as I did above and will see that we're still far away from tasks lasting for a few milliseconds...