On Thursday, 3 July 2025 at 21:56:03 UTC, kdevel wrote:
> import std;
extern (C) int sleep (int);
void main ()
{
defaultPoolThreads (8);
auto itemsstring = "a b c d e f g";
auto items = itemsstring
.split // split at ws
.filter!(s => s != "" && s[0] != '#')
// .array // uncomment for parallel execution
;
pragma (msg, typeof (items));
foreach (item; parallel (items)) {
sleep (1);
writeln (item);
}
}
This program prints the letters a to g with a 1 s pause between them.
Is that intended?
Apparently, yes.
ParallelForeach!R parallel(R)(R range)
{
static if (hasLength!R)
{
// Default work unit size is such that we would use 4x as many
// slots as are in this thread pool.
size_t workUnitSize = defaultWorkUnitSize(range.length);
return parallel(range, workUnitSize);
}
else
{
// Just use a really, really dumb guess if the user is too lazy to
// specify.
return parallel(range, 512);
}
}
Because filter has no length, it guesses it can hand the first 512 to one thread. Which is all of it.
In order to get the behavior you want, you have to specify the work unit size:
foreach (item; parallel (items, 1)) { // one unit per thread
Note that I was not aware of this, and I bet most people are not, even seasoned D developers.
-Steve