Saturday, April 29, 2017

Digest for comp.lang.c++@googlegroups.com - 12 updates in 3 topics

"Chris M. Thomasson" <invalid@invalid.invalid>: Apr 28 04:37PM -0700

On 4/28/2017 1:54 AM, Bonita Montero wrote:
>> of time in the server. ...
 
> Such a large number of threads is usually I/O-bound, so this is not a
> real problem then.
 
Btw, I agree with Ian, please try to make proper attributions.
"Chris M. Thomasson" <invalid@invalid.invalid>: Apr 28 06:00PM -0700

On 4/28/2017 1:54 AM, Bonita Montero wrote:
>> of time in the server. ...
 
> Such a large number of threads is usually I/O-bound, so this is not a
> real problem then.
 
Read all of:
 
http://tangentsoft.net/wskfaq
 
Old school, back in my winsock days.
"Chris M. Thomasson" <invalid@invalid.invalid>: Apr 28 06:31PM -0700

On 4/27/2017 9:48 PM, kushal bhattacharya wrote:
>> quite nicely, for mutexs... ;^)
 
> the method you mentioned ,could you plese give me some sample code,actually
> i cant really get the actual workflow here :)
 
Fwiw, here is some very crude pseudo-code that shows how a queue
per-thread can distribute the load. Like using a colander rather than a
single funnel. This has a single log thread but its assuming that
logging is not all that "frequent". The load is distributed by the fact
that each thread has its own mutex. Here is the crude pseudo-code:
 
Also this does not have any lifetime management (ref counting ect...)
wrt keeping request nodes alive in it:
_________________________
struct per_io_worker
{
// our local intrusive linked list node of workers
per_io_worker_list_node m_node;
 
// our local log queue
log_queue m_logq;
 
// our work loop... Infinity aside.
void work()
{
for (;;)
{
// wait for our io
raw_request* r = consume_io();
 
// queue our log request locally
m_logq.push(r);
 
// can I do something else?
//[... fill in the blank here ...];
}
}
};
 
// The logger!
struct log_io_worker
{
// a reference to a list of workers
per_io_worker_list& m_wlist;
 
// our personal log list
raw_request_list m_list;
 
// our work loop... Infinity aside.
void work()
{
// wait/sleep for signal
 
// gain requests in read access mode
m_wlist.read_lock();
for each worker in m_wlist
{
m_list.push_items(worker.m_logq.dequeue());
}
m_wlist.read_unlock();
 
// process log requests locally! :^)
for each raw_request in m_list
{
process_log(raw_request);
}
 
// dump it!
m_list.clear(); // empty it all out
}
};
_________________________
 
 
This example is crude, and does not show how to make it adaptable wrt
using try lock. Its high level and shows how per-thread queues can be
used by a single log thread. Wrt the wait/sleep part, well, we can
create a semaphore with timeout. Or build in some fancy convar logic for
this.
 
Can you grok this setup?
 
Sorry if I made a typo in the crude pseudo-code.
 
;^o
"Chris M. Thomasson" <invalid@invalid.invalid>: Apr 28 06:38PM -0700

On 4/28/2017 6:31 PM, Chris M. Thomasson wrote:
> m_list.push_items(worker.m_logq.dequeue());
> }
> m_wlist.read_unlock();
 
 
Notice the read lock here on the shared reference to the list of worker
threads. Well, if your app is rapidly creating and destroying many
threas, this can become a bottleneck as well. Fwiw, a thread
per-connection model does this wrt periods of load in which many clients
are connecting and disconnecting with minimal work in between. If each
connect requires a new thread, well, shi% happens man!
 
This read lock will scale if the action of adding and removing threads
from the list is very rare. This should be the norm.
Bonita Montero <Bonita.Montero@gmail.com>: Apr 29 01:23PM +0200

Asynchronous I/O saves rather memory for the other threeads than
CPU-load.
A voluntary context-switch on an current Windows on a current CPU
is only 1000-2000 clock-cycles. So when a thread blocks on I/O and
the core switches to another thread where I/O has terminated, that's
not much CPU-load. So AIO is saves rather memory for the thread's
stack than CPU-load.
AIO I/O is theoretically beneficial only when there's not much pro-
cessing between initiating and termiating AIO-requests. Otherwise
the queues would halt. So AIO is used normally in rare cases like
database-writer-threads.
"Chris M. Thomasson" <invalid@invalid.invalid>: Apr 29 01:36PM -0700

On 4/29/2017 4:23 AM, Bonita Montero wrote:
> Asynchronous I/O saves rather memory for the other threeads than
> CPU-load.
 
It also saves CPU load. It also reduces pressure on mutexs wrt hundreds
of threads pounding them.
 
> cessing between initiating and termiating AIO-requests. Otherwise
> the queues would halt. So AIO is used normally in rare cases like
> database-writer-threads.
 
This does not make sense to me. Context switching hundreds of active
threads, do to load, is absolutely terrible. AIO and IOCP is about
scaling. Avoiding the funnel is about scaling. Creating a server is
about scaling.
 
Also, again can you _please_ add proper _attributions_ Bonita.
"Chris M. Thomasson" <invalid@invalid.invalid>: Apr 29 02:06PM -0700

On 4/28/2017 6:31 PM, Chris M. Thomasson wrote:
> for each worker in m_wlist
> {
> m_list.push_items(worker.m_logq.dequeue());
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
There is an ambiguity here. the dequeue function implies that a single
object is removed. Well, in this scheme it would totally work, but I
really wanted a flush function that removed all of the items from the
queue in a single atomic operation. Basically, just like this:
 
https://groups.google.com/d/topic/comp.lang.c++/yt27gw0cbyo/discussion
(search the source code for the text "flush")... ;^)
 
Therefore, the line above the carets should read as:
 
m_list.push_items(worker.m_logq.FLUSH());
 
capital letter for emphasis in the pseudo-code. ;^)
 
 
Popping mad <rainbow@colition.gov>: Apr 29 02:11PM

What is the purpose of the double ampersand in this use of auto
 
http://en.cppreference.com/w/cpp/container/vector/push_back
 
#include <vector>
#include <iostream>
#include <iomanip>

int main()
{
std::vector<std::string> numbers;

numbers.push_back("abc");
std::string s = "def";
numbers.push_back(std::move(s));

std::cout << "vector holds: ";
for (auto &&i : numbers) std::cout << std::quoted(i) << ' ';
std::cout << "\nMoved-from string holds " << std::quoted(s) << '\n';
}
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Apr 29 09:16PM +0200

On 29-Apr-17 4:11 PM, Popping mad wrote:
> for (auto &&i : numbers) std::cout << std::quoted(i) << ' ';
> std::cout << "\nMoved-from string holds " << std::quoted(s) << '\n';
> }
 
In this context, where the type is deduced, the `&&` makes that type a
"universal reference" , also known as a "forwarding reference".
 
In effect, if `i` is bound to an rvalue expression (a temporary), then
type deduction plus the rules for collapsing of `&`-sequences make `i`
of type `T&&`, an rvalue reference. And if `i` is bound to an lvalue
expression, then those same rules make `i` of type `T&`, an ordinary
C++03 reference. This is the sort of shape shifting nature of a
universal reference.
 
For this particular case `i` is bound to an lvalue in each iteration of
the loop, and thus its type is `T&`, namely `std::string&`.
 
If the programmer was well aware of things and wrote that intentionally,
not just blindly copying what he/she had seen elsewhere, then the only
purpose I can think of would be to support a later modification of the
code where `i` might instead be bound to an rvalue.
 
In that case the reference makes the code compile and avoids copying the
value (in each iteration).
 
 
Cheers & hth.,
 
- Alf
kushal bhattacharya <bhattacharya.kushal4@gmail.com>: Apr 29 12:50AM -0700

Hi,
Is it possible to create a mutex pointer in c++?If so ,which is the best method to do so so that i could use it as a normal mutex to pass it to like lock_guard or to condition_variable's wait.Is it really possible ?
Thanks,
Kushal
Marcel Mueller <news.5.maazl@spamgourmet.org>: Apr 29 04:11PM +0200

On 29.04.17 09.50, kushal bhattacharya wrote:
> Hi,
> Is it possible to create a mutex pointer in c++?
 
What is a "mutex pointer"?
 
 
Marcel
Jorgen Grahn <grahn+nntp@snipabacken.se>: Apr 29 04:52PM

On Sat, 2017-04-29, Marcel Mueller wrote:
>> Hi,
>> Is it possible to create a mutex pointer in c++?
 
> What is a "mutex pointer"?
 
A pointer to a mutex, surely?
 
Mutex* my_mutex_pointer = &my_mutex;
 
/Jorgen
 
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
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: