Why does APL retain the thread numbers?
4 posts
• Page 1 of 1
Why does APL retain the thread numbers?
Stormwind rootserver running overnight, ⎕tnums:
0 14382 14356 14112 14051 13954 13310 13027 12860 12774 12362 12122 12092 12027 11983 11753 11737 11571 10704 10257 10201 10158 ... [ca 450 more]
Each time .net does an async callback and there is concurrency, eg. another packets is arriving async'ly while APL async'ly handles this packet, or the async callback in APL performs an async reply action (eg. socket.SendAsync), there seems to be born a new APL thread number.
Windows seems to invent new numbers... APL (and Windows?) seems to re-use numbers if there is no concurrency ongoing.
I recall well that John D has stated that APL stores the winthreadnr/aplthreadnr binding in order to improve something... performance? As such sounds smart. APL even does this up to a huge content in that binding pool, like up to gigabytes. Is this again really smart? Searching for a cached hit in such amount of data must also take time? And that slowly eats up all memory.
A problem here is that when i type )si (eg. in the case of callback fn errors), i get n-hundred pages of these
&14112 (system thread:5804)'s
into the session. Impossible to read.
I'd be happy to hear the indepth reason for cacheing the binding :-)? Naturally one could keep track of the APL threads and housekeep (delete) after use... But what's the smart way, performance-wise and other-wise?
Is this actually about something not getting properly deleted/Disposed?
0 14382 14356 14112 14051 13954 13310 13027 12860 12774 12362 12122 12092 12027 11983 11753 11737 11571 10704 10257 10201 10158 ... [ca 450 more]
Each time .net does an async callback and there is concurrency, eg. another packets is arriving async'ly while APL async'ly handles this packet, or the async callback in APL performs an async reply action (eg. socket.SendAsync), there seems to be born a new APL thread number.
Windows seems to invent new numbers... APL (and Windows?) seems to re-use numbers if there is no concurrency ongoing.
I recall well that John D has stated that APL stores the winthreadnr/aplthreadnr binding in order to improve something... performance? As such sounds smart. APL even does this up to a huge content in that binding pool, like up to gigabytes. Is this again really smart? Searching for a cached hit in such amount of data must also take time? And that slowly eats up all memory.
A problem here is that when i type )si (eg. in the case of callback fn errors), i get n-hundred pages of these
&14112 (system thread:5804)'s
into the session. Impossible to read.
I'd be happy to hear the indepth reason for cacheing the binding :-)? Naturally one could keep track of the APL threads and housekeep (delete) after use... But what's the smart way, performance-wise and other-wise?
Is this actually about something not getting properly deleted/Disposed?
- Tomas Gustafsson
- Posts: 101
- Joined: Mon Sep 19, 2011 6:43 pm
Re: Why does APL retain the thread numbers?
Hi Tomas,
I think the 2501 and 2502 I-Beams will help you.
Discard Thread on Exit R←2501⌶Y
Discard Parked Threads R←2502⌶Y
Please have a look at our 15.0 I-Beam documentation for more details.
Regards,
Vince
I think the 2501 and 2502 I-Beams will help you.
Discard Thread on Exit R←2501⌶Y
Discard Parked Threads R←2502⌶Y
Please have a look at our 15.0 I-Beam documentation for more details.
Regards,
Vince
- Vince|Dyalog
- Posts: 413
- Joined: Wed Oct 01, 2008 9:39 am
Re: Why does APL retain the thread numbers?
Thx Vince, i've heard there are new I-beams but that's not really what i wanted to know.
When trying to evaluate the importance if this, i'd like to hear what kind of performance hits or benefits there are in doing either way.
What's the advantage of retaining the thread bindings? If it's a matter of the interpreter having set up an entire new memory management instance, with housekeeping tables and whatnot, well that seems like a rather big job and i might not want that to happen each time a UDP packet comes in asynchronously. Hence the I-beam option of always clearing out the APL thread when completed becomes irrelevant, as that would always enforce a creation of a completely new binding next time.
If again retaining the binding keeps such a housekeeping instance alive but asleep, i wonder at which point (how many of them) it's beginning to cause noticeble overhead?
This is a behaviour that imho should be optimised. Leaving this at the users responsibility, to shooting 100% in blind, or leaving 100% alive, or always killing one sort of them but not the other, seems a bit rough? Is there no room for a thread pool-thinking, where APL could re-use the parked threads even if there is no exact hit in the earlier-made binding? That would keep the total amount of them low.
I'm bound to v. 14 for the moment, so i could (maybe) TKILL manually if it's worth doing so. And in v. 15, what's the guideline for knowing how to choose wisely?
When trying to evaluate the importance if this, i'd like to hear what kind of performance hits or benefits there are in doing either way.
What's the advantage of retaining the thread bindings? If it's a matter of the interpreter having set up an entire new memory management instance, with housekeeping tables and whatnot, well that seems like a rather big job and i might not want that to happen each time a UDP packet comes in asynchronously. Hence the I-beam option of always clearing out the APL thread when completed becomes irrelevant, as that would always enforce a creation of a completely new binding next time.
If again retaining the binding keeps such a housekeeping instance alive but asleep, i wonder at which point (how many of them) it's beginning to cause noticeble overhead?
This is a behaviour that imho should be optimised. Leaving this at the users responsibility, to shooting 100% in blind, or leaving 100% alive, or always killing one sort of them but not the other, seems a bit rough? Is there no room for a thread pool-thinking, where APL could re-use the parked threads even if there is no exact hit in the earlier-made binding? That would keep the total amount of them low.
I'm bound to v. 14 for the moment, so i could (maybe) TKILL manually if it's worth doing so. And in v. 15, what's the guideline for knowing how to choose wisely?
- Tomas Gustafsson
- Posts: 101
- Joined: Mon Sep 19, 2011 6:43 pm
Re: Why does APL retain the thread numbers?
Hello Thomas,
Dyalog maintains a "map" of .NET thread numbers to APL thread numbers. The map is required for cases (usually in GUI) where code that manipulates an object always needs to be run on the same thread. For example, if thread n creates a GUI object then typically only thread n can change properties of that object.
When such a thread has no stack, Dyalog puts the thread into a state (which we called "parked") where it will not get scheduled, until a subsequent .NET call requires code to be run on the same thread. There is still some overhead to having these parked threads in the workspace, and this overhead increases with the number of parked threads. It's hard to judge the comparable overhead of the parked threads versus the overhead of spinning up a new thread on each call. However, I suspect that if you are creating about 500 threads in an overnight (let's say an 8 hour run), then thread creation is "rare" and you'd see an improvement by disabling the parking with the ibeams, and have a new thread started for each call.
Now, we realised that in many cases the use of thread pools, and other thread creation models, make the thread map unnecessary, thus the introduction of the new ibeams in 15.0. As the interpreter is not aware of the use that threads are put to we can't really automate the process. However, there may be an argument for a global setting that disables the thread map for all threads in a process, I suspect you'd use that in Stormwind.
As an experiment it would be interesting if you were able to run Stormwind on version 15.0 and use the ibeams to disable the thread parking. You may or may not see a performance improvement due to fewer threads in the workspace. There have also been significant performance improvements elsewhere in 15.0.
Best Regards
John Daintree.
Dyalog maintains a "map" of .NET thread numbers to APL thread numbers. The map is required for cases (usually in GUI) where code that manipulates an object always needs to be run on the same thread. For example, if thread n creates a GUI object then typically only thread n can change properties of that object.
When such a thread has no stack, Dyalog puts the thread into a state (which we called "parked") where it will not get scheduled, until a subsequent .NET call requires code to be run on the same thread. There is still some overhead to having these parked threads in the workspace, and this overhead increases with the number of parked threads. It's hard to judge the comparable overhead of the parked threads versus the overhead of spinning up a new thread on each call. However, I suspect that if you are creating about 500 threads in an overnight (let's say an 8 hour run), then thread creation is "rare" and you'd see an improvement by disabling the parking with the ibeams, and have a new thread started for each call.
Now, we realised that in many cases the use of thread pools, and other thread creation models, make the thread map unnecessary, thus the introduction of the new ibeams in 15.0. As the interpreter is not aware of the use that threads are put to we can't really automate the process. However, there may be an argument for a global setting that disables the thread map for all threads in a process, I suspect you'd use that in Stormwind.
As an experiment it would be interesting if you were able to run Stormwind on version 15.0 and use the ibeams to disable the thread parking. You may or may not see a performance improvement due to fewer threads in the workspace. There have also been significant performance improvements elsewhere in 15.0.
Best Regards
John Daintree.
-
JohnD|Dyalog - Posts: 74
- Joined: Wed Oct 01, 2008 9:35 am
4 posts
• Page 1 of 1
Who is online
Users browsing this forum: No registered users and 1 guest
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group