Re: Threads: incompatibilities between C and C++?
Rani Sharoni wrote:
On May 20, 6:07 pm, Volker Lukas <vlu...@gmx.de> wrote:
Rani Sharoni wrote:
I also noticed a potential abstraction penalty associated with
std::thread.
Per the C++ standard 30.3.1.2/4 (thread construction): The *new
thread of execution executes* INVOKE(DECAY_- COPY(
std::forward<F>(f)), DECAY_COPY (std::forward<Args>(args))...)
with the calls to DECAY_COPY being evaluated in the constructing
thread.
This means that in general the caller thread has to wait for the
new thread copying - serialization penalty that doesn't exist for
the raw C interface.
Can you explain a bit more what exactly is the origin of the
performance penalty? You write that the caller has to wait for the
new thread to copy something - but I can not see why that is the
case. As is stated in the quote from the C++ standard above, the
copies are made in the calling thread.
One might argue to additional copying is allowed but then why
mandating the copying in the new thread?
Again, I only see a requirement that the calling thread makes a copy
of the function object and the arguments: "[...] with the calls to
DECAY_COPY being evaluated in the constructing thread." .
Question: How do you interpret "constructing thread"? Does this mean
to you the the new thread of execution, that which was just started,
or does it mean to you the old thread, that which constructed the
std::thread object?
To me, it means the latter.
BTW - can you debug into the GCC implementation to see if it waits?
VC for sure does.
I can not see anything which I would call "waiting", i.e. I do not see
any waiting on condition variables, mutexes, semaphores etc...
For this program,
-----------------------------------------------------------
#include <iostream>
#include <thread>
void tid(char const* loc) {
std::cout << loc << ", thread id = "
<< std::this_thread::get_id() << std::endl;
}
struct A {
A() { }
A(A const&) { tid("A(A const&"); }
A(A&&) { tid("A(A&&"); }
};
void f(A&&) { tid("f"); }
int main() {
try {
tid("main");
A a;
std::thread t(f, a);
t.join();
}
catch(...) { std::cout << "\nDuh!\n"; }
}
-----------------------------------------------------------
I get this output (GCC 4.7.0 + supplied library implementation):
main, thread id = 139890527434560
A(A const&, thread id = 139890527434560
A(A&&, thread id = 139890527434560
f, thread id = 139890510874368
So any copies of the function object and its argument are made in the
old thread. This is in line with my reading of the C++ standard (N3376
draft).
This is how std::thread is implemented for GCC:
http://gcc.gnu.org/viewcvs/trunk/libstdc++-
v3/include/std/thread?revision=184997&view=markup
and
http://gcc.gnu.org/viewcvs/trunk/libstdc++-
v3/src/c++11/thread.cc?revision=184997&view=markup
There is also an alternate implementation of std::thread, as part of
the LLVM project:
http://llvm.org/svn/llvm-project/libcxx/trunk/include/thread
http://llvm.org/svn/llvm-project/libcxx/trunk/src/thread.cpp
That implementation also makes the copies in the calling thread, like
with GCC.
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]