Slashdot Mirror


Linux 2.6 Multithreading Advances

chromatic writes "Jerry Cooperstein has just written an excellent article explaining the competing threading implementations in the upcoming 2.6 kernel for the O'Reilly Network."

20 of 194 comments (clear)

  1. Re:Call me stupid but by Minna+Kirai · · Score: 3, Informative

    Sigh, I'll do your web searching for you.

    Basically, while Linus was incommunicado sailing across the ocean, someone got jumpy and suggested 3.0 should be the next step.

    It might be more likely that it proceeds through 2.10 and higher before going to 3, though. Just to confuse the people who think version numbers are floating-point.

  2. Re:Non-threaded programs by Silh · · Score: 5, Informative

    While Quake 1 was developed on NEXT, the target platform at that time would have been DOS, so multithreading would be a bit of a problem...

    As to further licencees of the engine, revamping the engine to use multithreading was probably not a very high priority in making a game.

    On the other hand, for someone writing an engine from scratch is a different matter.

    --
    -- Silhouette
  3. Re:Actually, Quake II by Minna+Kirai · · Score: 3, Informative

    In terms of software archeology, there is an important intermediate ancestor.

    Quake's original networking was meant for LANs only- the fact that it was even barely playable over the internet suprised the authors.

    idsoftware soon released QuakeWorld free to Quake owners. It used the same interface and most of the graphics resources as Quake, so its arguably not a different program. But it came as a separate executable, with many Quake features removed (like monsters). And most importantly, the networking code was entirely re-written.

    It is that code that QuakeII and successors derived from.

  4. Re:I don't see why the two are mutually exclusive. by jpc · · Score: 2, Informative

    If you have hundreds of thousands of connections you should be using aio, which is the new scalable replacement for lots of polls...

  5. Yes and No by krmt · · Score: 5, Informative

    I don't understand this all that well myself, but I did just read the whitepaper linked to in the article written by Ingo Molnar and Ulrich Drepper. From the looks of things, NGPT's M:N model will cause a lot more problems because of the difficulty of getting the two schedulers (userspace and kernelspace) to dance well together.

    By sticking with the 1:1 solution that's currently used in the kernel and the NPTL model, there's really only the kernel scheduler to worry about, making things run a lot more smoothly generally. I'd imagine latency being a big issue with M:N (I'm pretty sure that it was mentioned in the whitepaper). I haven't read the other side of the issue, but I think that pretty graph in the O'Reilly article says it all performance-wise.

    There are other issues though, like getting full POSIX compliance with signal handling. The 1:1 model apparently makes signal handling much more difficult (I don't know anything about the POSIX signaling model, but there's a paper about it on Drepper's homepage that could probably shed some light on the subject if you were so inclined. There are other issues in the current thread model that have to be dealt with in a new 1:1 model (and are) such as a messy /proc directory when a process has tons of threads.

    From the whitepaper, it seems that the development of the O(1) scheduler was meant to facilitate the new thread model they've developed, which I hadn't thought about before even though it makes sense. There's still some issues to work through, but both models look promising. If the signal handling issues can be resolved it looks like from the article that NPTL's model will win on sheer performance.

    As for making them both come with the kernel, that's really really difficult, since this stuff touches on some major pieces of the kernel like signal handling. The same way you're only going to get one scheduler and VM subsystem, you're only going to get one threading model. You're able to patch your own tree to your heart's content, but as per a default install, there can be only one.

    --

    "I may not have morals, but I have standards."

  6. Re:Non-threaded programs by DarkHelmet · · Score: 3, Informative
    Yeah yeah yeah... When life isn't perfect, blame Abrash...

    Troll! ;)

    ---
    (And yes, Mike Abrash did WinQuake, not Carmack)

    --
    /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i
  7. LWN by KidSock · · Score: 5, Informative

    has a nice article about the state of threading on Linux. See the Sept. 27th Weekly Edition.

  8. Re:Someone should start a site.... by taviso · · Score: 4, Informative

    Someone should start a site that covers long term issues, rather than the week by week stuff I've found on the web... or maybe someone has, and I'm just too out of the loop....

    KernelTrap.

    --
    ex$$
  9. Mode switching times. by zak · · Score: 2, Informative

    Switching between user and kernel mode takes time. If all your primitive operations are implemented in user mode, synchronisation (for instance) takes several cycles in the best case (resource is free, lock it), and a bit over a hundred in the worst (resource is busy, context switch). When you also add the user/kernel mode transition (which may be a couple dozen cycles on some RISCs but takes more than a hundred on some x86 architectures), you can see how performance may degrade.

  10. Re:Oh crap, I wish I didn't have to say this... by khuber · · Score: 2, Informative
    IBM's System 360 had multithreading in 1964.

    Multics had multithreading in the early 1970s.

    Windows was still launched from DOS in 1992.

    Please go back to your "innovating" with Windows.

    -Kevin

  11. Re:I don't see why the two are mutually exclusive. by rweir · · Score: 5, Informative

    Now, for ANY 1:1 threading system, I can't just create x * 10^5 threads because the overhead would be colossal.

    Actually, it's kind of famous for that.

  12. Re:Someone should start a site.... by Salsaman · · Score: 4, Informative

    Try lwn.net. They have a weekly overview of the kernel status. Since they moved to a subscription model, you have to pay to see the latest news, but previous weeks can be viewed for free.

  13. Re:So are they both useful? by barneyfoo · · Score: 2, Informative

    With the new O(1) scheduler and other improvements made by ingo molnar scheduling kernel threads is no longer a major bottleneck. Besides, NGPT goes against the linux philosophy of minimally invasive changes to the kernel api, and it's doubtful linus will accept it into the kernel.

  14. Re:How about scheduling & thread-specific stor by Juergen+Kreileder · · Score: 3, Informative
    In the current version priorities only work SCHED_RR and SCHED_FIFO (both require superuser privileges), SCHED_OTHER (the default policy) doesn't support changing priorities.

    Regarding thread specific data access: If your LinuxThreads library uses floating stacks (for ix86 this means it has been built with --enable-kernel=2.4 and for i686) it already will be faster.

    For other TLS enhancements take a look at http://people.redhat.com/drepper/tls.pdf.

  15. Re:I don't see why the two are mutually exclusive. by Quixote · · Score: 3, Informative
    Now, for ANY 1:1 threading system, I can't just create x * 10^5 threads because the overhead would be colossal

    If you read the article, it shows benchmarks done by the NPTL folks which shows a 2x improvement in thread start/stop timings over NGPT (which itself is a 2x improvement over POLT (plain old Linux threads)).

    Read more about NPTL here (PDF file).

  16. Re:Kernel vs user doesn't make sense by inquis · · Score: 3, Informative

    Two words: context switches.

    Whenever execution switches between user mode and kernel mode, a context switch is required. Context switches are expensive.

    Inidentally, this is one of the advantages of the microkernel approach: by severely limiting the code that must be run in kernel space, you can minimize context switches between kernel and user mode and save a lot of time.

  17. Re:Non-threaded programs by Salamander · · Score: 5, Informative
    applications where deadlocks or race conditions would be an integral problem in a multithreaded implementation whilst a single thread has none of these problems.

    That's a common myth. In fact, there are some kinds of deadlock that do go away, but there are also some kinds that merely change their shape. For example, the need to lock a data structure to guarantee consistent updates goes away, and so do deadlocks related to locking multiple data structures. OTOH, resource-contention deadlocks don't go away. You might still have two "tasks" contending for resources A and B, except that in the non-threaded model the tasks might be chained event handlers for some sort of state machine instead of threads. If task1 tries to get A then B, and task2 tries to get B then A, then task1's "B_READY" and task2's "A_READY" events will never fire and you're still deadlocked. Sure, you can solve it by requiring that resources be taken in order, but you can do that with threads too; the problem's solvable, but isn't solved by some kind of single-threading magic.

    I've written several articles on this topic for my website in the past. In case anyone's interested...

    --
    Slashdot - News for Herds. Stuff that Splatters.
  18. Re:Kernel vs user doesn't make sense by mesocyclone · · Score: 3, Informative

    Typically, the microkernel approach INCREASES the number of context switches. However, a microkernel also normally has very fast context switches.

    The context switches are increased because a single operation (say, and I/O read) requires switching into the kernel from the user process, and then out into a device driver. A non-microkernel would have the device driver in the kernel. This is just an example - it may be that the switch is to the file system manager instead, or some other helper process. The point is that the nature of a microkernel is to have lots of helper processes that perform what are normally macro-kernel functions.

    Context switches typically are expensive because they involve more than just a switch into kernel mode. They are likely to involve some effort to see if there is other work to do (such as preempt this thread). They may involve some privelege checks, and some statistical gathering.

    A microkernel just does less of this stuff.

    BTW... the first elegant running micro-kernel I ran into was the original Tandem operating system. The kernel was primarily a messaging system and scheduler (I think scheduling *policy* may have been handled by a task, btw). I/O, file system activity, etc was handled by privileged tasks. It was very elegant, and conveniently fit into their "Non-Stop (TM)" operation.

    --

    The only good weather is bad weather.

  19. Re:I thought it was 3.0? by WNight · · Score: 3, Informative

    There aren't really any incompatibilities with older code, so you don't need to go to a new kernel version like you would if you broke anything.

    In one of the discussions with Linus on this issue he said there was a planned change that broke something but it wouldn't be in for this version. Because that would warrant a major version change of its own, he didn't want to go from 2.5 to 3.0 then from 3.3 or something to 4.0, he'd rather go from 2.9(or so) to 3.0, and avoid the version inflation.

    I agree. There's no stigma in having a product numbered 1.x or 2.x, it simply means you got it right early on, without needing to break old applications too often.

  20. Re:Non-threaded programs by Salamander · · Score: 3, Informative
    Every context switch burns hundreds, if not tens of thousands, of clock cycles.

    A well-designed multi-threaded implemention will organize its thread usage in such a way that under light load and/or on a single processor it will not have significantly more context switches than a single-threaded equivalent. Under such conditions it will exhibit the same performance characteristics as that single-threaded version, and yet it will also be able to take advantage of inherent parallelism and multiple processors when they exist. Been there.

    Bad multithreaded implementations schedule so many computationally active threads that TSE switches are inevitable. Bad multithreaded implementations force two context switches per request as work is handed off between "listener" and "worker" threads. Bad multithreaded implementations do lots of stupid things, but not all multithreaded implementations are bad. The main overhead involved in running a well-designed multithreaded program on a uniprocessor is not context switches but locking, and that will be buried in the noise. Done that.

    A handful of extra context switches per second and a fraction of a percent of extra locking overhead are a small price to pay for multiprocessor scalability.

    It's trivial to run multiple copies of a single-threaded program on the different CPUs, and let them interact over IPC.

    Trivial, but stupid. You really will context-switch yourself to death that way, as every occasion where you need to coordinate between processes generates at least one IPC and every IPC generates at least one context switch (usually two or more)...and those are complete process/address-space switches, not relatively lightweight thread switches. That's how to build a really slow application.

    this approach scales trivially to large numbers of networked processors.

    No, it doesn't. There's simply no comparison between the speed of using the same memory - often the same cache on the same processor, if you do things right - and shipping stuff across the network...any network, and I was working on 1.6Gb/s full-duplex 2us app-to-app round-trip interconnects five years ago. Writing software to run efficiently on even the best-provisioned loosely-coupled system is even more difficult than writing a good multithreaded program. That's why people only bother for the most regularly decomposable problems with very high compute-to-communicate ratios.

    catastrophic failure of one process does not necessarily corrupt the state of another process. (While one thread crashing is almost certain to bring down an entire multi-threaded program.)

    Using separate processes instead of threads on a single machine might allow your other processes to stay alive if one dies, but your application will almost certainly be just as dead. The causal dependencies don't go away just because you're using processes instead of threads. In many ways having the entire application go down is better, because at least then it can be restarted. When I used to work in high availability, a hung node was considered much worse than a crash, and the same applies to indefinite waits when part of a complex application craps out.

    --
    Slashdot - News for Herds. Stuff that Splatters.