Comments on Replacing C
Eric S. Raymond
esr at thyrsus.com
Mon Jan 9 02:38:24 UTC 2017
Hal Murray <hmurray at megapathdsl.net>:
>
> How well do the languages/systems you are considering support threading?
Both Go and Rust have good concurrency support. This is a theme in
pretty much all recent language designs that is driven by the collapse
of Dennard scaling and the ubiquity of multiprocessor systems.
> I think we should be careful not to over-focus on translating the current
> single-threaded code.
Qualified agreement. My intended strategy to to refactor for
re-entrancy using Go's or Rust's object system as a natural way to
encapsulate task-local storage that would be (but is not yet)
thread-local storage in a multithreaded implementation. Once that
architectural cleanup is done, exploiting concurrency will be
relatively simple.
> What should our code look like in the long term? Will crypto chew up a lot
> of cycles? Could a busy server support more clients by running several
> threads in parallel on multiple CPUs?
>
> Is there any reason not to use multiple threads?
I can vaguely imagine some unpleasant interactions with the peer-selection
algorithms. I think this is proably manageable.
> Would we actually gain anything from multiple threads? Would they all merge
> back together queuing up for the crypto hardware? I've seen good comments
> about the performance of Intel's crypto accelerators but don't remember the
> context. Is the extra hardware one per chip, or one per CPU?
I don't know the answer to this question yet. But I also don't care
yet, because the things that need to be done to support future concurrency
(mainly, the ruthless elimination of global shared state) are good in
themselves for reducing defect rates.
> Maybe we should write some test code.
Too soon.
> Eric has occasionally said non-good things about threads. The context was
> mostly the DNS stuff from the current code which is admittedly ugly. (Maybe
> we should add fixing that to the list.)
>
> I've always considered threads to be no-big-deal. Maybe that's because I
> learned about them when I worked with people who got the architecture right
> and the language supported it. Mesa/Cedar from Xerox/Parc back in the
> 70s/80s had locking supported by the language. You could say "ENTRY
> PROCEDURE" and it would lock the module lock when entering that procedure.
> "INTERNAL PROCEDURE" meant that it could only be called if you already had
> the lock. There was another form for locking a record (aka struct).
Yeah, so you had decent primitives. That helps a lot. I didn't realize just
how much until recently.
Go has been opening my eyes about this. In the past I avoided writing
threaded code, and distrusted threaded code written by others, because
my experience was that threaded code written with what C programmers
think of as standard primitives (shared storage, locks, semaphores,
mutexes) scaled badly. It was just too hard to avoid unplanned
interactions. The code was fussy, complex, and hard to read.
Ever since reading about occam in the 1980s I'd had a suspicion that CSP
was the Right Thing - a suspicion which seems to me to have been strongly
confirmed by my recent experience using Go channels.
Posix threads felt like fumbling for razor blades in the dark. Go
channels are a concurrency toolkit that is expressive, simple, and (no
shit) *beautiful*. Decent primitives really matter. I think I'm going
to miss these a whole lot if we go with Rust.
--
<a href="http://www.catb.org/~esr/">Eric S. Raymond</a>
More information about the devel
mailing list