New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Thread creation time is hypersensitive #7298
Comments
From @jlokierCreated by @jlokierPlease take the time to read this report carefully, as it appears to The time to create a new thread is highly sensitive to conditions that Adding a single short, semantically void comment line to a large The effect is repeatable: a script which starts threads slowly does so It is also sensitive to names: changing the name of some modules in The time variation is accompanied by variation in the amount of memory There's strong evidence that this is a Perl bug, not a libc thread I have tried to produce examples of two Perl programs which differ That's why I haven't included example code. If there's a need for it, I noticed this problem when trying to speed up a script which uses So I removed references to all IO::* modules, and it made the script Thanks, Perl Info
|
From @iabynOn Sun, May 16, 2004 at 11:25:12PM -0000, Jamie Lokier wrote:
thanks for the report.
Perl is just using the system's malloc() library. If that does lots of Failing that ...
... could you supply the files, thanks. Dave. -- |
The RT System itself - Status changed from 'new' to 'open' |
From @jlokierDave Mitchell via RT wrote:
My mistake - in fact it's doing hundreds of tiny mprotect() calls, not The call chains for the bulk of mprotect() calls look like: #0 0x420dbc60 in mprotect () from /lib/tls/libc.so.6 You were correct, it's due to malloc(), and these are clearly I compared the strace output (system calls) of the slow and fast test I tried to use ltrace to count the number of malloc() calls, but These multitude of mprotect() calls are clearly a Glibc implementation The main complaint is about the huge variation in thread creation
It would be quite time consuming as I have 56k dialup, and also the I'd much prefer if someone else can reproduce the problem, although I I just had a fine example of two scripts differing by a couple of Oh, surprise... I have noticed that changing to a different directory In other words, it's tough to find a reproducible test case, and it's The method for finding a test case in your own environment is: 1. Start with a large script that loads modules and defines lots 2. Append this: for (0..9) { 3. Time it with "time perl script.pl". If the time between 4. Remove chunks of the program, e.g. function definitons or comments 5. Having found that removing some function or block of code makes
Ok. I don't expect they'll demonstrate the problem in your I have 10 files, one of them is a shell script which uses "env" to I don't want to send this source publically (there's a lot of Thanks, |
From @iabynOn Tue, May 18, 2004 at 12:34:38AM +0100, Jamie Lokier wrote:
Unless this is an artifact of gdb running on an optimised build,
Are these truely trivial changes, or do they change the amount of modules The creation of a new thread mainly involves the recursive duplication One thing you might want to do is use gdb to set a breakpoint on
I'll try to find some time in the next few days to play with this on a RH9 -- |
From mooring@acm.orgOn Tue, May 18, 2004 at 12:34:38AM +0100, Jamie Lokier wrote:
This smacks of an alignment issue. Try adding an environment If it's an alignment problem, the slowdown will likely disappear and -- |
From @jlokierDave Mitchell wrote:
I suspect gdb too. This is a standard install with no debugging info.
Yes, they are are. Sometimes a comment is enough. However due to the $ diff -u fast.pl slow.pl Inline Patch--- fast.pl 2004-05-19 12:58:53.000000000 +0100
+++ slow.pl 2004-05-19 12:59:03.000000000 +0100
@@ -1276,7 +1276,7 @@
# from the local EBCDIC code page if there is one. The caller is
# responsible for doing this.
-sub http_server_100_continue(;$) {
+sub http_server_101_continue(;$) {
}
for (0..9) {
real 0m0.816s Testing slow.pl real 0m2.824s
Notice how in the above example, the only difference is in how a My first guess was that the recursive duplication was traversing some
That's a great idea. Testing fast.pl: There's a difference (why?) but it's small. (Btw, duplicating it under gdb is tricky because gdb calls a shell to Something interesting from gdb, though: Each time I interrupt slow.pl, That suggests Perl_ptr_table_fetch is taking much more time in Testing fast.pl: Ok, that confirms Perl_ptr_table_fetch is running slower in slow.pl, That looks a likely culprit: the hash function in Perl_ptr_table_fetch It would be sensitive to the memory layout. (But so sensitive as to Fixing that hash function looks likely to fix the problem. Let's UV hash = PTR2UV(sv); (Actually that's the 5.8.3 source for illustration, and the breakpoint Testing fast.pl up to the first "new thread" write(): Testing fast.pl up to the second "new thread" write(): Testing slow.pl up to the first "new thread" write(): Testing slow.pl up to the second "new thread" write(): We found it: Perl_ptr_table_fetch is running very slowly, most likely It's not clear to my why a trivial change of the name of a subroutine, -- Jamie |
From @iabynOn Wed, May 19, 2004 at 03:42:25PM +0100, Jamie Lokier wrote:
Great catch!!! Thanks for spotting this vital clue :-) It turns out that the code in ptr_table_store(), which stores old to new I managed to get a reproducable case that went from 2 secs to 23 secs The change below to bleedperl fixes the immediate problem, although Dave. -- Change 22830 by davem@davem-percy on 2004/05/19 20:17:55 [perl #29637] Thread creation time is hypersensitive Affected files ... ... //depot/perl/sv.c#742 edit Differences ... ==== //depot/perl/sv.c#742 (text) ==== @@ -10400,11 +10400,11 @@ assert(tbl); |
From @iabynThe following patch to bleed (slightly) improves the hashing algorithm Dave. -- Change 22831 by davem@davem-percy on 2004/05/19 21:02:04 improve hashing algorithm for ptr tables in perl_clone: Affected files ... ... //depot/perl/sv.c#743 edit Differences ... ==== //depot/perl/sv.c#743 (text) ==== @@ -10374,13 +10374,19 @@ +#if (PTRSIZE == 8) void * assert(tbl); |
From @jlokierDave Mitchell wrote:
There are good hashes for power-of-two size tables. The approx golden My runs with gdb in the "good" case (fast.pl) indicate an average -- Jamie |
From @jlokierDave Mitchell wrote:
I can confirm that your change appears to fix the problem. I recompiled the exact Perl source package that Red Hat 9 uses, but So I patched the binary. On Red Hat 9, with perl-5.8.0-88.3, changing This removed the time variation in creating new threads - now both The real program I was having trouble with - a fairly complex I will continue to use the binary-patched version of Perl on my Thanks for noticing the real bug. -- Jamie |
From @JohnPeacockJamie Lokier wrote:
RedHat (and many other distros) make custom patches to their Perl source; What I would recommend doing (instead of binary hacking) is to obtain the RedHat John -- |
From @jlokierJohn Peacock wrote:
That's what I did. Hence "source package". I built from the source RPM. Patching the existing binary did the trick. I'm sure the bug is -- Jamie |
From @nwc10On Thu, May 20, 2004 at 09:47:00PM +0100, Jamie Lokier wrote:
Mmm. Yes. I think that I have a solution to Arthur's immediate problem with
Yes, that's my opinion too :-)
Thanks for your help in tracking this down. Nicholas Clark |
From @nwc10On Wed, May 19, 2004 at 11:23:19PM +0100, Jamie Lokier wrote:
Yes, but it's hashing byte by byte on variable length character strings. So yes, we would benefit from looking to find an external, good, algorithm
I agree. But I'm not well read on these things, so I don't know what Nicholas Clark |
@iabyn - Status changed from 'open' to 'resolved' |
Migrated from rt.perl.org#29637 (status was 'resolved')
Searchable as RT29637$
The text was updated successfully, but these errors were encountered: