threads

V

Vespasian

The CPAN documentation on perl threads state the overhead of creating
a thread is rather large. Anyone know why or could point me to a
website that explains the reason.

TIA,
ves
 
R

robic0

The CPAN documentation on perl threads state the overhead of creating
a thread is rather large. Anyone know why or could point me to a
website that explains the reason.

TIA,
ves
Less than a process. I can only imagine the win32 api on that
platform. Its all about state and context, as the threads
switch, the manager has to save the execution state of the
leaving thread, then install the newly running thread state.
State is all the things you don't want to know about.
Low level stuff like the adresses of the currently running
and newly running code address (IP) and things like where
data is, like the Stack and also the registers. So, it basically
takes an image of the state of the cpu registers and all of the
segment pointers relating to code path and data, then reinstates
the new one. Back and forth it goes. On windows I think theres
64k threads that state can be saved for.

You should take a course on assembly to fully understand
machine mechanics. Others will bullshit this out forever
just wait and see....
 
T

Tassilo v. Parseval

Also sprach robic0:
Less than a process. I can only imagine the win32 api on that
platform. Its all about state and context, as the threads
switch, the manager has to save the execution state of the
leaving thread, then install the newly running thread state.

[...]

This has absolutely nothing to do with the OP's question of why Perl
threads have such a high overhead on creation (as opposed to threads in
other environments).

The actual reason is the fact that Perl threads are interpreter threads,
meaning that a whole Perl interpreter has to be cloned. The C structure
backing up an instance of one interpreter is already very big: It has
over a hundred members. But that is not all. Each and every variable
created thus far has to be duplicated as well.

And there is some remarkable book-keeping involved, so it's not only a
matter of doing the equivalent of a few memcpies.

Incidentally, this message cropped up on the perl5-porters list this
morning:

ithreads clone time is crap. However, if anyone is interested and
motivated, read on for how we might improve it.

The ithreads cloning is done by copying everything in the old thread
to the new thread. The clone code keeps track of what it's already
cloned by using a custom hash table to map the pointer in the old
thread to the pointer in the new thread. This is all the ptr_table_*
code.

The hash is structured like the regular perl hash code - an array of
linked lists, with a hash function used to map the pointer into an
index in that array. The current hash function is:

#if (PTRSIZE == 8)
# define PTR_TABLE_HASH(ptr) (PTR2UV(ptr) >> 3)
#else
# define PTR_TABLE_HASH(ptr) (PTR2UV(ptr) >> 2)
#endif


The idea of the hash function is to spread the possible input values
evenly around. It seems that this hash function is pretty lousy.

[...]

Tassilo
 
X

xhoster

Vespasian said:
The CPAN documentation on perl threads state the overhead of creating
a thread is rather large. Anyone know why or could point me to a
website that explains the reason.

Because it copies the interpreter itself and all the data.

Xho
 
V

Vespasian

Thanx, Tassilo -- that's the answer I was looking for

ves

Also sprach robic0:
Less than a process. I can only imagine the win32 api on that
platform. Its all about state and context, as the threads
switch, the manager has to save the execution state of the
leaving thread, then install the newly running thread state.

[...]

This has absolutely nothing to do with the OP's question of why Perl
threads have such a high overhead on creation (as opposed to threads in
other environments).

The actual reason is the fact that Perl threads are interpreter threads,
meaning that a whole Perl interpreter has to be cloned. The C structure
backing up an instance of one interpreter is already very big: It has
over a hundred members. But that is not all. Each and every variable
created thus far has to be duplicated as well.

And there is some remarkable book-keeping involved, so it's not only a
matter of doing the equivalent of a few memcpies.

Incidentally, this message cropped up on the perl5-porters list this
morning:

ithreads clone time is crap. However, if anyone is interested and
motivated, read on for how we might improve it.

The ithreads cloning is done by copying everything in the old thread
to the new thread. The clone code keeps track of what it's already
cloned by using a custom hash table to map the pointer in the old
thread to the pointer in the new thread. This is all the ptr_table_*
code.

The hash is structured like the regular perl hash code - an array of
linked lists, with a hash function used to map the pointer into an
index in that array. The current hash function is:

#if (PTRSIZE == 8)
# define PTR_TABLE_HASH(ptr) (PTR2UV(ptr) >> 3)
#else
# define PTR_TABLE_HASH(ptr) (PTR2UV(ptr) >> 2)
#endif


The idea of the hash function is to spread the possible input values
evenly around. It seems that this hash function is pretty lousy.

[...]

Tassilo
 
I

Ilya Zakharevich

[A complimentary Cc of this posting was sent to
Tassilo v. Parseval
threads have such a high overhead on creation (as opposed to threads in
other environments).

The actual reason is the fact that Perl threads are interpreter threads,
meaning that a whole Perl interpreter has to be cloned.

Sorry, Tassilo, but IMO this is pure BS (and I wrote the reasons why
many times). The reason is that for thread creation Perl uses a
mechanism (cloning) which was designed as a way to circumvent a
completely unrelated problem (absense of fork() in Win* environment)
[and circumvent it only partially].
The C structure backing up an instance of one interpreter is already
very big: It has over a hundred members. But that is not all. Each
and every variable created thus far has to be duplicated as well.

Did you run any benchmark? In my measurements, cloning takes about
1.5 ORDERS OF MAGNITUDE more time than one needed to create the
initial environment.

Hope this helps,
Ilya
 
T

Tassilo v. Parseval

Also sprach Ilya Zakharevich:
Tassilo v. Parseval
threads have such a high overhead on creation (as opposed to threads in
other environments).

The actual reason is the fact that Perl threads are interpreter threads,
meaning that a whole Perl interpreter has to be cloned.

Sorry, Tassilo, but IMO this is pure BS (and I wrote the reasons why
many times). The reason is that for thread creation Perl uses a
mechanism (cloning) which was designed as a way to circumvent a
completely unrelated problem (absense of fork() in Win* environment)
[and circumvent it only partially].

I strongly doubt that this was the only reason. Perl's ithreads have
another advantange: Due to the fact that nothing is shared by default,
the conversion of a non-threaded program to using threads is made
easier and will in general keep the program functional without much
further adjustments.

Besides: In my posting I didn't say anything about the why of Perl's
threading model. So even if the fork-emulation on Win32 was the actual
reason, why would not mentioning it render my statement BS?
Did you run any benchmark? In my measurements, cloning takes about
1.5 ORDERS OF MAGNITUDE more time than one needed to create the
initial environment.

And that surprises you? By the time the cloning happens, a lot more data
is there than at process start-up time: tmp-stacks and pads are usually
already well filled to name but one example. This is all spelled out in
ext/threads/threads.xs:perl_ithread_create().
Hope this helps,

Not really. You seem to be implying that all I wrote was nonsense and
wrong. And yet, nothing you wrote contradicts what I said.

Tassilo
 
R

robic0

The CPAN documentation on perl threads state the overhead of creating
a thread is rather large. Anyone know why or could point me to a
website that explains the reason.

TIA,
ves

Well, I warned you all the bullshit would come out, and it did.
Unix didn't have threads until Microsoft did, er showed them how.
So it seems windows is the natural api threading model.
The bullshit you read from the previous posters has to do with alot
of things. One is they don't know what a real os native,
kernel mode threading model is. Otherwise, they wouldn't be so
arogant as to push off what I said, which is the root of a
threading model.

That model is to save the state of the current thread of
execution, then switch to a different state. There is NO
making a duplicate copy of CODE for each thread. That
includes the Perl interpreter (forking, or spawning
a new process is different as it has a seperate "address
space". You know what that is don't you?)

Since there is no duplication of code in a new thread of
execution, theres only auto data, stack data and registers
that include segment pointers like SP, IP, to save state for.
Globals are inherintly shared in the native model and must
be specifically locked for exclusive access.

Note the difference between a new process and a new thread.
That being threads share the same address space, processes
do not. Threading means global (shared) data can be accessed by
any running thread in the process when its got focus
(aka: a time-slice).

But how does a interpreted language do threading?
Datawise, if its possible that language global
data within a thread (and we're talking threaded code
that are subroutines in Perl) can be modified within
a subroutine without data locks, then the only way the
interpreter can survive without forcing subroutines
to lock that data, is to create duplicate set of data
(auto-variables) for each thread. Remember, your Perl
subroutine is not the thread. The thread envelope has
to be enlarged so that your subroutine is the currently
running code that was called by the interpreter (all threads
of execution are called by a single copy of the interpreter)
with a different set of auto data. Auto data is that which is
declared within the block (I believe its lexical in Perleaz).

Given that, what seperate data is needed for each thread
in Perl. Well clearly, if Perl calls your code in a single
thread, all the data of the caller (interpreter) has to be
"auto-data" of the scope of the interpreter. Otherwise for
those to be considered global would need a lock for almost
every module in perl since they access main variables all
the time. The overhead now is on "auto data". Each
new thread creates a new copy of the interpreters auto data.
The scope of the currently running code has expanded to
now be the block of the interpreter, not of the single
subroutine.

Therein lies the absolute bullshit !!!
 
I

Ilya Zakharevich

[A complimentary Cc of this posting was sent to
Tassilo v. Parseval
Sorry, Tassilo, but IMO this is pure BS (and I wrote the reasons why
many times). The reason is that for thread creation Perl uses a
mechanism (cloning) which was designed as a way to circumvent a
completely unrelated problem (absense of fork() in Win* environment)
[and circumvent it only partially].
I strongly doubt that this was the only reason. Perl's ithreads have
another advantange: Due to the fact that nothing is shared by default,

[Some may consider this as a major disadvantage.] Anyway, if the
interpreter in the newly created thread would be created "from
scratch", nothing would be shared too, so I could not immediately see
why this may be an argument in favor of cloning.
Besides: In my posting I didn't say anything about the why of Perl's
threading model. So even if the fork-emulation on Win32 was the actual
reason, why would not mentioning it render my statement BS?

Your statement was:

Please pay attention to "meaning that".
And that surprises you? By the time the cloning happens, a lot more data
is there than at process start-up time: tmp-stacks and pads are usually
already well filled to name but one example. This is all spelled out in
ext/threads/threads.xs:perl_ithread_create().

"Creation of the initial environment" includes the time to fill these
"tmp-stacks etc". Also, one could get an impression that having these
"stuff" filled is some kind of advantage. AFAIU, it is not.
You seem to be implying that all I wrote was nonsense and wrong.

Sorry if you got this impression. I thought I separated the
questionable parts from the rest.
And yet, nothing you wrote contradicts what I said.

Please allow me to disagree.

Yours,
Ilya
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,176
Messages
2,570,950
Members
47,503
Latest member
supremedee

Latest Threads

Top