Re: Mystery Threads
Re: Mystery Threads
- Subject: Re: Mystery Threads
- From: Aandi Inston <email@hidden>
- Date: Thu, 29 Sep 2016 08:37:24 +0100
My thoughts are general, not specific to Mac OS... The idea that the best
performance comes from threads = #CPUs is attractive, but will work only if
the threads do not sleep and do not interfere with each other. A classic
example is dividing up a complex calculation that runs without touching the
disk, reading large arrays, or sharing variables.
To construct a case where more than #CPUs might help, consider a thread
which sets up and reads from a network connection, then does something
trivial and repeats. If you have threads=#CPUs, each thread will start and
issue a network read. Then all the threads will wait for a reply and the
CPU is idle. More threads might help. But they might overwhelm the network,
so it might not be a good plan to have thousands. Exactly the same applies
if the thead reads or writes the disk. The thread might read the disk
deliberately, or it might get a page fault. More threads might help, but
the bottleneck is likely to be the disk, so the number of threads is almost
irrelevant.
Where threads run simultaneously on different CPUs, you want for best
performance to allow each CPU to work with data in its cache. Where one
thread writes a memory location that is read by another thread, the CPUs
are likely to have to flush their cache, and the multi-CPU performance
becomes that of an uncached CPU, which can be terrible. The hardware issues
here are complex and I haven't kept up with them; perhaps cache sharing has
improved.
On 29 September 2016 at 08:15, Gerriet M. Denkmann <email@hidden> wrote:
> I have a big array (like a few GB) which is operated upon by some
> functions.
> As these functions act purely local, an obvious idea is:
>
> - (void)someFunction
> {
> nbrOfThreads = ...
> sizeOfBigArray = ... a few GB
> stride = sizeOfBigArray / nbrOfThreads
>
> dispatch_apply( nbrOfThreads, queue, ^void(size_t idx)
> {
> start = idx * stride
> end = start + stride
>
> index = start
> while ( index < end )
> {
> mask = ...
> bigArray[index] |= mask
> index += … something positive…
> }
> }
> )
> }
>
> As my computer has just 8 CPUs, I thought that using nbrOfThreads > 8
> would be silly: adding overhead without gaining anything.
>
> Turns out this is quite wrong. One function (called threadHappyFunction)
> works more than 10 times faster using nbrOfThreads = a few ten-thousand (as
> compared to nbrOfThreads = 8).
>
> This is nice, but I would like to know why can this happen.
>
> Another function does not like threads at all:
>
> - (void)threadShyFunction
> {
> nbrOfThreads = ...
> uint64_t *bigArrayAsLongs = (uint64_t *)bigArray
> sizeOfBigArrayInLongs = ...
> stride = sizeOfBigArrayInLongs / nbrOfThreads
>
> uint64_t *template = ...
> sizeOfTemplate = not more than a few dozen longs
>
> dispatch_apply( nbrOfThreads, queue, ^void(size_t idx)
> {
> start = idx * stride
> end = start + stride
>
> offset = start
>
> while ( offset + sizeOfTemplate < end )
> {
> for ( i = 0 ..< sizeOfTemplate )
> bigArrayAsLongs[offset + i] |= template[i]
> offset += sizeOfTemplate
> }
> }
> )
> }
>
> This works, but for nbrOfThreads > 1 it gets slower instead of faster. Up
> to hundred times slower for moderately big nbrOfThreads.
> This really bothers me.
> Why are the threads seemingly blocking each other?
> What is going on here?
> How can I investigate this?
>
> Gerriet.
>
> P.S. macOS 12, Xcode 8, ObjC or Swift.
>
>
> _______________________________________________
>
> Cocoa-dev mailing list (email@hidden)
>
> Please do not post admin requests or moderator comments to the list.
> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
>
> Help/Unsubscribe/Update your Subscription:
>
> This email sent to email@hidden
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden