Re: Chat server : Threading in select call



On Feb 12, 3:22 pm, William Ahern <will...@xxxxxxxxxxxxxxxxxxxxxxxxx>
wrote:

None of those solve the problem that an unexpected page fault can lead
to a latency spiral.

The same problem occurs with multi-threaded code, unless you have just as
many CPUs as threads.

No, that's not true. The page fault will cause another thread to run
on the same CPU. In fact, you will have the problem (at least in
principle) unless you have *more* threads than CPUs.

A page fault will increase load which will decrease
the resources which you otherwise had dedicated. A thread which causes a
page fault or a cache line miss might not relinquish the CPU as quickly,
effecting concurrency granularity and increasing latency. (If we're talking
swap, well I run most of my boxes without swap.)

A thread that causes a page fault will relinquish the CPU immediately.
It will not hold the CPU for the duration of the page fault.

As for parallelism, well, even event-oriented designs can make use of
threads, or even better, multiple processes. If you go the latter route, you
probably won't have to bother with lock contention as much.

I'm not sure what you mean. How did "event-oriented designs" get into
this?

Realistically
stdio shouldn't be used for anything that is performance critical,
that's just how it is. Maybe you can paper over some of the worst bits
by adding more threads, but you have to be very careful, and you now
have an additional thing you have to care about for every line of code
that you run.

I don't know how stdio got into this.

I assume he's alluding to issues like logging to stderr, which might have
been redirected to a file, or otherwise might block on a write. The issue
can occur with syslog, too, though. I admit this isn't usually of much
concern when writing pure threaded apps. In practice, though, its not much
of a concern for me, either. When logging is heavy enough its just as easy
to write a separate process to eat the log data and prevent the logging
process(es) from blocking. Indeed, in any event the kernel manages to
usually do this just fine with the buffer cache; and in those extreme cases
when it can't, syslog is just as likely to slow down and block any or all of
the threads writing to it, so....

You wouldn't let all your threads write to syslog anyway. In any
event, even if syslog blocked every thread that wrote to it, so long
as logging is rare, it won't hurt you even if it does block every
thread that touches it.

The point is, in a single-threaded application, if your logging starts
blocking, your hosed. In a multi-threaded application, you're not.
That means you must make absolutely sure your logging never, ever
blocks. If you succeed, congratulations, you just went through a lot
of trouble solving a problem you could easily have avoided by starting
with a better architecture. If you fail, your server will have
problems with latency and possibly latency spirals.

Sure, you just have to make sure that no line anywhere can cause a
problem when run at the same time as any other line anywhere ... and
it's well known that solving for N**2 is much easier than solving
for N.

This is a nonsensical thing to say. Code doesn't conflict with code,
only data conflicts. In any event, you have the same issue with single-
threaded code -- you have to make sure that every possible way you
could put something down works with every possible way you might pick
it back up.

Mutex. Lock contention. Deadlock.

These are bugs. Every kind of server can have bugs. There are some
bugs only single-threaded servers suffer from and some only multi-
threaded servers suffer from. So what?

With multi-threaded apps every lock in the
source code creates a window of opportunity for subtle bugs to arise from
odd interactions between huges swaths of code; and in places where the
author may have had no clue he needed to be concerned about the issue. The
more data sharing/contention, the more difficult it can become to manage
this window. I suppose valgrind may have helped in this area; but I don't
write much heavily threaded code anymore.

That's really just not true. If the locks are properly architected in
the first place, these kinds of problems just don't come up. In any
event, you have the same issues in single-threaded programs where
unexpected blocking is fatal.

We can argue over more bugs versus fewer bugs in various
architectures, and you can make some good points and so can I. But the
point is, you start with numerous strikes against you in a single-
threaded architecture. With multiple threads, you can carefully choose
where you put concurrency and needn't put it everywhere. With a single
thread, you have no choices -- every single line of code must not ever
block or you are totally screwed.

Certainly I've found it infinitely easier to debug event-oriented apps than
multi-threaded apps. I guess with all the multiple cores selling now the
tools will only keep getting better.

Most multi-threaded apps are event-oriented.

DS
.



Relevant Pages

  • RE: FreeBSD 4.11 P13 Crash
    ... It happened again even with a new CPU and new PowerSupply. ... IPFilter, ... page fault while in kernel mode ... Okay this time my kernel was recompiled so there are no ...
    (freebsd-hackers)
  • Re: new em problems on HEAD
    ... I have no idea, i see no evidence that its the em driver at fault, do you? ... device = '82573E Intel Corporation 82573E Gigabit Ethernet ... <ACPI PCI bus> on pcib0 ... CPU supports Enhanced Speedstep, ...
    (freebsd-current)
  • understanding a panic / crash dump
    ... GDB is free software, covered by the GNU General Public License, and you are ... page fault while in kernel mode ... CPU: AMD AthlonMP 2000+ ... pci0: <PCI bus> on pcib0 ...
    (freebsd-stable)
  • Re: book on assembly language
    ... but what I meant is ASM is a machine (CPU) specific ... | mov ecx D$eax + TString.Length | dec ecx ... | mov eax D$eax + TString.Pchar ... But many bugs in my code comes from changing/extending the ...
    (alt.lang.asm)
  • freebsd current crash
    ... page fault while in kernel mode ... acpi0: on motherboard ... acpi_cpu0: on acpi0 ... <ACPI PCI bus> on pcib0 ...
    (freebsd-current)