Sunday, December 28, 2014

Digest for comp.lang.c++@googlegroups.com - 19 updates in 4 topics

Martijn Lievaart <m@rtij.nl.invlalid>: Dec 28 01:33PM +0100

On Thu, 25 Dec 2014 11:57:43 -0800, Öö Tiib wrote:
 
>> invented.
 
> That reads too generic claim to be believable. Sounds skewed. Do you
> have any links to papers to point at?
 
I agree its way too generic but:
 
> 2) Multithreading does waste lot of time to synchronize access
> to shared data, processes do not share data.
 
This doesn't have to be the case at all. A well written threaded program
needs very little synchronization. Memory management can be a problem,,
but that can be solved with per thread (or per strand) allocators.
 
In fact, the main synchronization would be for interthread communication,
something which is inherently heavyweight between multiple programs as
well.
 
M4
Mr Flibble <flibble@i42.co.uk>: Dec 28 01:28PM

On 28/12/2014 12:33, Martijn Lievaart wrote:
 
>> That reads too generic claim to be believable. Sounds skewed. Do you
>> have any links to papers to point at?
 
> I agree its way too generic but:
 
Nonsense; processes are heavyweight, threads are lightweight; processes
have their own address space; threads share an address space. It seems
obvious to me that threads scale better than processes.
 
/Flibble
"Öö Tiib" <ootiib@hot.ee>: Dec 28 11:46AM -0800

On Sunday, December 28, 2014 2:35:51 PM UTC+2, Martijn Lievaart wrote:
 
> This doesn't have to be the case at all. A well written threaded program
> needs very little synchronization. Memory management can be a problem,,
> but that can be solved with per thread (or per strand) allocators.
 
Cross-task message passing is usually more pleasant form of
synchronization than the mutexes and semaphores. It can become less
scalable when the resulting traffic (sharing of data) is large but like
you said it does not have to be the case always. When the threads keep
anyway majority of data separate (using such message-passing and separate
memory management) then there are no clear difference from (and so
advantage versus) processes.
 
> In fact, the main synchronization would be for interthread communication,
> something which is inherently heavyweight between multiple programs as
> well.
 
Good example of rather scalable server-side architecture is Node.js.
There the applications are single threaded (as rule) yet it can
service millions of simultaneous connections. It is worth to consider
and to compare such things a bit.

One important point for multiprocessing (that I did not initially add)
is security. Huge applications with numerous modules are usually made
by rather multiple teams (sometimes located on multiple continents).
It is unpleasant to find out that someone got illegal access to your
module's data because some other module has security vulnerability.
 
I find multi-threading clearly better than multi-processing for solving
embarrasingly parallel problems. On all other cases it is worth to
consider what is better in situation under hand.
"Öö Tiib" <ootiib@hot.ee>: Dec 28 12:27PM -0800

On Sunday, December 28, 2014 3:29:11 PM UTC+2, Mr Flibble wrote:
 
> Nonsense; processes are heavyweight, threads are lightweight; processes
> have their own address space; threads share an address space. It seems
> obvious to me that threads scale better than processes.
 
Sharing of memory between processes typically means that two processes
share access to same page of virtual memory. Each thread has its own stack anyway. The code and any static immutable data can be shared by overcommit
of 'fork'. There certainly is overhead but it may be outweighed by
simplicity and robustness of single-threadedness.
 
For example: The measured overhead per process is 6MB. A thread becomes
overburdened with I/O and starts to lag at 10K connections. So it forks
additional process to service other 10K connections. The overhead is
split as 60 bytes per connection but there's no need to do per-thread
allocators or other such tricks.
Ian Collins <ian-news@hotmail.com>: Dec 29 10:08AM +1300

嘱 Tiib wrote:
> additional process to service other 10K connections. The overhead is
> split as 60 bytes per connection but there's no need to do per-thread
> allocators or other such tricks.
 
Which isn't an uncommon model.
 
Web servers tend to run multiple processes, databases run multiple
processes with shared memory.
 
There are some tasks with tightly coupled data where threads are the
best or only viable solution, others where data separation makes a lot
more sense. I guess two opposite examples are the qemu emulator (some
VMs on this system run scores of threads) and Samba, which runs a
process per client.
 
--
Ian Collins
Mr Flibble <flibble@i42.co.uk>: Dec 28 09:15PM

On 28/12/2014 20:27, Öö Tiib wrote:
> share access to same page of virtual memory. Each thread has its own stack anyway. The code and any static immutable data can be shared by overcommit
> of 'fork'. There certainly is overhead but it may be outweighed by
> simplicity and robustness of single-threadedness.
 
IPC between processes is not as simple as threads communicating within a
shared address space; I would argue that multi-threaded is no less
simple or robust than multi-process.
 
 
> additional process to service other 10K connections. The overhead is
> split as 60 bytes per connection but there's no need to do per-thread
> allocators or other such tricks.
 
That is far more complicated than a threadpool within the same process.
 
/Flibble
Ian Collins <ian-news@hotmail.com>: Dec 29 10:33AM +1300

Mr Flibble wrote:
 
> IPC between processes is not as simple as threads communicating within a
> shared address space; I would argue that multi-threaded is no less
> simple or robust than multi-process.
 
Then you are at odds with Google's Chrome developers, See
http://blog.chromium.org/2008/09/multi-process-architecture.html
 
A multi-threaded solution may well be simpler, but that simplicity comes
at a cost.
 
>> split as 60 bytes per connection but there's no need to do per-thread
>> allocators or other such tricks.
 
> That is far more complicated than a threadpool within the same process.
 
But less vulnerable to bugs or malicious code..
 
--
Ian Collins
Mr Flibble <flibble@i42.co.uk>: Dec 28 11:07PM

On 28/12/2014 21:33, Ian Collins wrote:
>>> allocators or other such tricks.
 
>> That is far more complicated than a threadpool within the same process.
 
> But less vulnerable to bugs or malicious code..
 
I hope you didn't get the impression that I think you shouldn't solve
problems with multiple processes; I am simply claiming that threads
scale better than processes.
 
/Flibble
Ian Collins <ian-news@hotmail.com>: Dec 29 12:26PM +1300

Mr Flibble wrote:
 
> I hope you didn't get the impression that I think you shouldn't solve
> problems with multiple processes; I am simply claiming that threads
> scale better than processes.
 
I don't thinks it's a clear cut these days. Samba is a reasonable
counter example: on one of my servers I can see several hundred smbd
processes in a file share zone. These are all independent, so there
would be little point in running multiple threads. On the other hand
the storage pool process runs a pool of 256 threads, which does make
sense given its workload.
 
--
Ian Collins
mathewji <itoneymathew@gmail.com>: Dec 28 11:29AM -0800

With:
 
int day = 0;
while(true) {
cout << "number: ";
cin >> day }
 
Inputting anything besides an int into day, causes nonstop output of "number: ". I found a solution as:
 
int day = 0;
while(true) {
cout << "number: ";
if (cin >> day) day;
else break; }
 
Anyone know why this happens?
Marcel Mueller <news.5.maazl@spamgourmet.org>: Dec 28 08:43PM +0100

On 28.12.14 20.29, mathewji wrote:
> cout << "number: ";
> cin >> day }
 
> Inputting anything besides an int into day, causes nonstop output of "number: ". I found a solution as:
 
If no int can be read from cin then the >> operator does nothing but
setting an error flag which you did not check.
 
> if (cin >> day) day;
> else break; }
 
> Anyone know why this happens?
 
Now you checked for the error by implicitly converting cin (istream) to
bool.
 
 
Marcel
Ian Collins <ian-news@hotmail.com>: Dec 28 08:09PM +1300

EQuestionAnswers Inc wrote:
 
> This is our website http://www.equestionanswers.com loaded with
> C,C++, VC++,MFC,COM,DCOM, DLL question and answers, targeted for
> interviews and self-study. Hope you like this forum.
 
With examples like this:
 
#include
template
T swap(T &a, T &b)
{
T temp;
temp = a;
a = b;
b = temp;
}
void main()
{
int i = 10, j = 20;
swap(i, j);
cout << "Values i, j " << i << ", " << j;
float a = 3.14, b = -6.28;
swap(a, b);
cout << "Values a, b " << a << ", " << b;
}
 
One to avoid.
 
--
Ian Collins
JiiPee <no@notvalid.com>: Dec 28 11:56AM

On 28/12/2014 07:09, Ian Collins wrote:
> cout << "Values a, b " << a << ", " << b;
> }
 
> One to avoid.
 
yes should be like:
 
|template <class T>void swap (T& a, T& b)
{
T c(std::move(a)); a=std::move(b); b=std::move(c);
}
 
Isn't it? Lets say a and b are objects containing 1 million characters. Then the
swap would copy 3 times those arrays. But with move copy would not be done. Right?
 
Or does the optimizer possibly do/add move automatically even if doing the swap without
std::move? I guess not in this case.
 
 
|
JiiPee <no@notvalid.com>: Dec 28 12:00PM

On 28/12/2014 07:09, Ian Collins wrote:
> cout << "Values a, b " << a << ", " << b;
> }
 
> One to avoid.
 
oh yeah, and the
#include
template
 
and no return (or rather should have void), heh. But also that move
should be used, isn't it?
Ian Collins <ian-news@hotmail.com>: Dec 29 08:03AM +1300

JiiPee wrote:
> T c(std::move(a)); a=std::move(b); b=std::move(c);
> }
 
> Isn't it?
 
I wasn't even looking at the details, there where so many other errors
it wasn't worth the trouble.
 
As soon as anyone sees "void main()" in an example, the only safe option
is to close the browser tab!
 
--
Ian Collins
JiiPee <no@notvalid.com>: Dec 28 07:08PM

On 28/12/2014 19:03, Ian Collins wrote:
> it wasn't worth the trouble.
 
> As soon as anyone sees "void main()" in an example, the only safe
> option is to close the browser tab!
 
ye the void as well. So it would be like 4 issues total I guess ?
 
Also imo best return is: return EXIT_SUCCESS;
I dont like return 0; :)
jononanon@googlemail.com: Dec 28 12:39AM -0800

On Sunday, December 28, 2014 12:12:09 AM UTC+1, Paavo Helde wrote:
> std::shared_ptr.
 
> Cheers
> Paavo
 
Maby you did not realize this...
 
Please give me some examples using your type pvector above.
Do some push_back and initializer list...
 
Just to give some examples of what does NOT work:
 
typedef std::vector<std::unique_ptr<int>> pvector;
 
pvector vec1 = {new int{1}}; // error
pvector vec2 = {std::unique_ptr<int>(new int{2})}; // error
pvector vec3;
vec3.push_back(new int{3}); // error
vec3.push_back(std::unique_ptr<int>(new int{3})); // error
 
That's why (I think that) in this particular case you need the version given by me in a previous post.
 
As I mentioned above...
Paavo Helde <myfirstname@osa.pri.ee>: Dec 28 04:21AM -0600

jononanon@googlemail.com wrote in
 
> Please give me some examples using your type pvector above.
> Do some push_back and initializer list...
 
The unique_ptr constructor is explicit, so one needs to spell it out when
creating these objects.
 
This works for me:
 
#include <vector>
#include <memory>
 
typedef std::unique_ptr<int> pint;
typedef std::vector<pint> pvector;
 
int main() {
pvector vec3;
vec3.push_back(pint(new int{ 3 }));
}
 
 
The initializer list version is failing though. I am not so familiar with
the initializer lists to say if and how they should work. Maybe my
compiler (VS2013) is still deficient.
 
>> Yip, what makes this interesting is the fact that std::unique_ptr
>> cannot
> be copied (in order to prevent double frees!)
 
Yes, but it can be moved, which makes it possible to put it in (C++11-
compatible) STL containers.
 
Cheers
Paavo
Paavo Helde <myfirstname@osa.pri.ee>: Dec 28 04:36AM -0600

Nobody <nobody@nowhere.invalid> wrote in
>> it hard to maintain its class invariants).
 
> Another issue is that STL classes typically don't have virtual
> destructors.
 
This is only a (potential) issue if you allocate them dynamically, but
this would not make much sense anyway. The STL containers perform any
needed dynamic allocations in inside, so there is no need to allocate the
container objects themselves dynamically. If I want to transfer them
somehow from one memory location to another there are swap() and C++11
move operations.
 
OK, maybe you have a point in that the people feeling an urge to derive
from std::vector might feel a similar urge to allocate it dynamically
(and delete unsafely) ;-)
 
Cheers
Paavo
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page.
To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com.

No comments: