<?xml version='1.0' encoding='UTF-8'?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" version="2.0">
  <channel>
    <title>checkedthreads: bug-free shared memory parallelism - comments</title>
    <link>https://yosefk.com/cgi-bin/comments.cgi?post=blog/checkedthreads-bug-free-shared-memory-parallelism#comments</link>
    <description>Comments on "checkedthreads: bug-free shared memory parallelism" by Yossi Kreinin</description>
    <docs>http://www.rssboard.org/rss-specification</docs>
    <generator>Yossi Kreinin's ugly publishing software</generator>
    <image>
      <url>https://yosefk.com/blog/self.jpg</url>
      <title>checkedthreads: bug-free shared memory parallelism - comments</title>
      <link>https://yosefk.com/cgi-bin/comments.cgi?post=blog/checkedthreads-bug-free-shared-memory-parallelism#comments</link>
      <width>144</width>
      <height>144</height>
    </image>
    <language>en</language>
    <lastBuildDate>Sun, 31 May 2026 13:00:04 +0000</lastBuildDate>
    <item>
      <title>Yossi Kreinin</title>
      <link>https://yosefk.com/cgi-bin/comments.cgi?post=blog/checkedthreads-bug-free-shared-memory-parallelism#comment-3064</link>
      <description><![CDATA[<html><head>
</head><body><p>No, no formal/full coverage stage done during compilation. Works
pretty well though. Try it.</p>
]]></description>
      <pubDate>Mon, 29 Aug 2016 08:14:00 +0000</pubDate>
      <dc:creator>Yossi Kreinin</dc:creator>
    </item>
    <item>
      <title>zong</title>
      <link>https://yosefk.com/cgi-bin/comments.cgi?post=blog/checkedthreads-bug-free-shared-memory-parallelism#comment-3062</link>
      <description><![CDATA[<html><head>
</head><body><p>Just had a look a the github documention.</p>
<p>So are are verifying ONLY the code paths / code orders which are
triggered by the test input?</p>
<p>Or is there a more formal/full coverage stage done during
compilation???</p>
<p></p>]]></description>
      <pubDate>Mon, 29 Aug 2016 03:13:00 +0000</pubDate>
      <dc:creator>zong</dc:creator>
    </item>
    <item>
      <title>Yossi Kreinin</title>
      <link>https://yosefk.com/cgi-bin/comments.cgi?post=blog/checkedthreads-bug-free-shared-memory-parallelism#comment-1945</link>
      <description><![CDATA[<html><head>
</head><body><p>I'm not saying you can't implement fork/join on top of goroutines
(you can); I'm only pointing out what happens if you have shared state
and you use a goroutine to access that shared state – that you eliminate
data races but not race conditions, which is obvious to some but
surprising to others.</p>
<p></p>]]></description>
      <pubDate>Sun, 23 Jun 2013 20:08:00 +0000</pubDate>
      <dc:creator>Yossi Kreinin</dc:creator>
    </item>
    <item>
      <title>Levi</title>
      <link>https://yosefk.com/cgi-bin/comments.cgi?post=blog/checkedthreads-bug-free-shared-memory-parallelism#comment-1944</link>
      <description><![CDATA[<html><head>
</head><body><p>I am not typically a Go apologist, but I think you've
mischaracterized Go's concurrency model. Although it supports
nondeterministic concurrency, it also supports deterministic
concurrency. Go's synchronization is based on channels, which come in
two forms: buffered and unbuffered. Unbuffered channels create a
rendezvous point–a write cannot complete until the other end executes a
read, and vice versa.</p>
<p>You can do a fork/join in Go by creating an unbuffered channel per
goroutine fork. There is no question then which goroutine returned a
result. If you spawn a goroutine for each iteration of a loop (the
fork), then loop again to read from each channel (the join), you will
get the exact same result every time. The order in which the goroutines
get scheduled and actually complete may vary, but that will not be
observable by your program.</p>
<p>Of course, you would have to do some hacking in the guts of Go in
order to use your checking tools with it, but the fork/join model itself
is one model that is supported by Go's primitives.</p>
<p></p>]]></description>
      <pubDate>Sun, 23 Jun 2013 19:10:00 +0000</pubDate>
      <dc:creator>Levi</dc:creator>
    </item>
    <item>
      <title>Yossi Kreinin</title>
      <link>https://yosefk.com/cgi-bin/comments.cgi?post=blog/checkedthreads-bug-free-shared-memory-parallelism#comment-1943</link>
      <description><![CDATA[<html><head>
</head><body><p>If you're the Uri that I think you are, then you know all of this all
too well except for the part where it's a dynamic simple-shaped
dependency DAG instead of a static arbitrarily-shaped dependency DAG :)
(Which is the more general is hard to tell; qsort is better expressed
with this fork/join stuff whereas task parallel graphs are better
handled by the arbitrarily shaped graphs. Which is the more gnarly is
obvious...)</p>
<p></p>]]></description>
      <pubDate>Thu, 04 Apr 2013 08:08:00 +0000</pubDate>
      <dc:creator>Yossi Kreinin</dc:creator>
    </item>
    <item>
      <title>Uri</title>
      <link>https://yosefk.com/cgi-bin/comments.cgi?post=blog/checkedthreads-bug-free-shared-memory-parallelism#comment-1942</link>
      <description><![CDATA[<html><head>
</head><body><p>Amazing staff. Thanks !</p>
<p></p>]]></description>
      <pubDate>Thu, 04 Apr 2013 06:47:00 +0000</pubDate>
      <dc:creator>Uri</dc:creator>
    </item>
    <item>
      <title>Yossi Kreinin</title>
      <link>https://yosefk.com/cgi-bin/comments.cgi?post=blog/checkedthreads-bug-free-shared-memory-parallelism#comment-1941</link>
      <description><![CDATA[<html><head>
</head><body><p>It's indeed generic in the sense that you can do a parallel_invoke or
some such where you give N different functions instead of having an
index running from 0 to N.</p>
<p>It's actually <em>less</em> generic performance-wise if you want what
the paper that I cited calls "non-strict fork-join" – that is, code
which can wait, not just for stuff it spawned, but for other stuff as
well – as you'll be able to do with most task-based fork-join
interfaces, and as you won't be able to do with just parallel_for and
parallel_invoke.</p>
<p>Why the restriction?</p>
<p>Because (A) I don't believe the difference in performance due to the
extra sync options is significant in real life (though I could easily
come up with a contrived example where it s); and (B) because it's damn
hard to verify generic dependency DAGs compared to the very simple
fork-join DAGs – in fact you hit the "NP-hardness" of poset
dimension.</p>
<p>I hope to blog about it in detail; it's actually covered not-so-badly
in the old post – <a href="http://www.yosefk.com/blog/making-data-races-manifest-themselves.html" rel="nofollow">http://www.yosefk.com/blog/making-data-races-manifest-themselves.html</a>
– except that it spells things in terms of some other framework and it's
older and I understood less back then (for instance, it says that the
trouble with locks is just that you can forget to lock or that you can
deadlock; in fact the biggest trouble with locks is stuff along the
lines of the maze race example.)</p>
<p>The upshot is that I'm doing generic graphs at work but I don't think
the world needs them, really; I might add them to checkedthreads in the
future though.</p>
<p></p>]]></description>
      <pubDate>Wed, 03 Apr 2013 11:54:00 +0000</pubDate>
      <dc:creator>Yossi Kreinin</dc:creator>
    </item>
    <item>
      <title>Miguel Osorio</title>
      <link>https://yosefk.com/cgi-bin/comments.cgi?post=blog/checkedthreads-bug-free-shared-memory-parallelism#comment-1940</link>
      <description><![CDATA[<html><head>
</head><body><p>Got it! So that's what you meant with "The upshot is that reordering
every pair of independent instructions is trivial with fork/join code
and very hard with raw threads.".</p>
<p>Your approach is generic because in this context, fork-join and
parallel-for are actually interchangeable, right? A "generic" fork-join
could spawn n threads, each doing a different job. The parallel-for
would just be a case where n threads are spawned doing the same job, but
with different data payloads.</p>
<p></p>]]></description>
      <pubDate>Wed, 03 Apr 2013 11:35:00 +0000</pubDate>
      <dc:creator>Miguel Osorio</dc:creator>
    </item>
    <item>
      <title>Yossi Kreinin</title>
      <link>https://yosefk.com/cgi-bin/comments.cgi?post=blog/checkedthreads-bug-free-shared-memory-parallelism#comment-1939</link>
      <description><![CDATA[<html><head>
</head><body><p>It's true that you could reverse the outer loop(s) but there's still
a boatload of orders in which inner loops can run. What the two orders I
mentioned are sufficient for is just <strong>reordering every pair of
independent instructions</strong> (that is, every two instructions that
could run in parallel). It's a rather weak statement about the order of
things – too weak to catch all the bugs in fact as I mentioned, though
strong enough to catch them all together with memory interception.</p>
<p>As an example, consider:</p>
<p>i=0 { j=0 j=1 j=2 } i=1 { j=0 j=1 j=2 }</p>
<p>And:</p>
<p>i=1 { j=2 j=1 j=0 } i=0 { j=2 j=1 j=0 }</p>
<p>Where i is the outer index and j is the inner index. Here, if you
pick two instructions belonging to two different serial code blocks that
could run in parallel, then these two code blocks have now been
reversed. But this is not the only way to achieve the effect, nor does
it imply anything stronger about the order of things.</p>
<p></p>]]></description>
      <pubDate>Wed, 03 Apr 2013 11:01:00 +0000</pubDate>
      <dc:creator>Yossi Kreinin</dc:creator>
    </item>
    <item>
      <title>Miguel Osorio</title>
      <link>https://yosefk.com/cgi-bin/comments.cgi?post=blog/checkedthreads-bug-free-shared-memory-parallelism#comment-1938</link>
      <description><![CDATA[<html><head>
</head><body><p>First of all, thank you for such good reading material, Yossi! My
first visit to this blog was by following a link from Carmack's twitter
feed, if I recall correctly. Ended up reading the whole shabang in
almost one go!</p>
<p>I was inspired by <a href="http://en.wikipedia.org/wiki/Algorithmic_skeleton" rel="nofollow">http://en.wikipedia.org/wiki/Algorithmic_skeleton</a> to
write my own APIs for parallel code, and guess what? To date, the most
basic one I've written was fork-join. Parallel loops are implemented
using that.</p>
<p>I have one or two questions though. I didn't understand very well
your example of the nested loops. That only two orderings are necessary.
Don't all iterations of each parallel-for run concurrently? So in one
run, I might have:</p>
<p>——–&gt; Time<br>
i = 0; i = 1; i = 2;</p>
<p>But another run might be:</p>
<p>——–&gt; Time<br>
i = 1; i = 2; i = 0;</p>
<p>That's different from the strict reverse ordering, right? (2; 1;
0)</p>
<p>Or is it that what actually matters is that, since it's fork-join,
the only threads that are actually doing work are always the innermost
loops, since all the remaining higher level ones are instead "waiting in
parallel"?</p>
<p>Not sure if I rubber-ducked you :P.</p>
<p>Cheers!</p>
<p></p>]]></description>
      <pubDate>Wed, 03 Apr 2013 03:51:00 +0000</pubDate>
      <dc:creator>Miguel Osorio</dc:creator>
    </item>
    <item>
      <title>Yossi Kreinin</title>
      <link>https://yosefk.com/cgi-bin/comments.cgi?post=blog/checkedthreads-bug-free-shared-memory-parallelism#comment-1937</link>
      <description><![CDATA[<html><head>
</head><body><p>CC0 and and especially the very short unlicense – nice stuff. I ain't
fiddling with this anymore though... Maybe next time.</p>
<p></p>]]></description>
      <pubDate>Wed, 03 Apr 2013 00:47:00 +0000</pubDate>
      <dc:creator>Yossi Kreinin</dc:creator>
    </item>
    <item>
      <title>Yossi Kreinin</title>
      <link>https://yosefk.com/cgi-bin/comments.cgi?post=blog/checkedthreads-bug-free-shared-memory-parallelism#comment-1936</link>
      <description><![CDATA[<html><head>
</head><body><p>What annoys me about these things is that they're a virus; the first
thing they require is "redistribute me when you redistribute the code".
Oh well...</p>
<p></p>]]></description>
      <pubDate>Tue, 02 Apr 2013 21:53:00 +0000</pubDate>
      <dc:creator>Yossi Kreinin</dc:creator>
    </item>
    <item>
      <title>Aristotle Pagaltzis</title>
      <link>https://yosefk.com/cgi-bin/comments.cgi?post=blog/checkedthreads-bug-free-shared-memory-parallelism#comment-1935</link>
      <description><![CDATA[<html><head>
</head><body><p>Yes, unfortunate though it is, you really cannot just say “do
whatever you want” if you want to minimise the amount of headaches for
everyone else. Sigh.</p>
<p>(I had been using MIT because I was not aware of 2-clause BSD until
now. Thanks for finding that.)</p>
<p></p>]]></description>
      <pubDate>Tue, 02 Apr 2013 19:16:00 +0000</pubDate>
      <dc:creator>Aristotle Pagaltzis</dc:creator>
    </item>
    <item>
      <title>Name</title>
      <link>https://yosefk.com/cgi-bin/comments.cgi?post=blog/checkedthreads-bug-free-shared-memory-parallelism#comment-1934</link>
      <description><![CDATA[<html><head>
</head><body><p>There is also the UNLICENSE:</p>
<p><a href="http://unlicense.org/" rel="nofollow">http://unlicense.org/</a></p>
<p>The popular sqlite database uses something similar to this.</p>
<p></p>]]></description>
      <pubDate>Tue, 02 Apr 2013 18:28:00 +0000</pubDate>
      <dc:creator>Name</dc:creator>
    </item>
    <item>
      <title>Name</title>
      <link>https://yosefk.com/cgi-bin/comments.cgi?post=blog/checkedthreads-bug-free-shared-memory-parallelism#comment-1933</link>
      <description><![CDATA[<html><head>
</head><body><p>The most permissive license is CC0:<br>
<a href="http://creativecommons.org/publicdomain/zero/1.0/legalcode" rel="nofollow">http://creativecommons.org/publicdomain/zero/1.0/legalcode</a></p>
<p>It's lawyer-approved, and doesn't force the recipient to reproduce
the copyright notice in source / binaries and whatnot.</p>
<p></p>]]></description>
      <pubDate>Tue, 02 Apr 2013 18:21:00 +0000</pubDate>
      <dc:creator>Name</dc:creator>
    </item>
    <item>
      <title>Yossi Kreinin</title>
      <link>https://yosefk.com/cgi-bin/comments.cgi?post=blog/checkedthreads-bug-free-shared-memory-parallelism#comment-1932</link>
      <description><![CDATA[<html><head>
</head><body><p>OK; so it's FreeBSD 2-clause license... Argh.</p>
<p></p>]]></description>
      <pubDate>Tue, 02 Apr 2013 07:47:00 +0000</pubDate>
      <dc:creator>Yossi Kreinin</dc:creator>
    </item>
    <item>
      <title>Yossi Kreinin</title>
      <link>https://yosefk.com/cgi-bin/comments.cgi?post=blog/checkedthreads-bug-free-shared-memory-parallelism#comment-1931</link>
      <description><![CDATA[<html><head>
</head><body><p>I would, but I'm not sure it will appease the type of lawyer people
are worrying about.</p>
<p>I'm shopping for a license now... I really don't want to uglify every
file...</p>
<p></p>]]></description>
      <pubDate>Tue, 02 Apr 2013 07:23:00 +0000</pubDate>
      <dc:creator>Yossi Kreinin</dc:creator>
    </item>
    <item>
      <title>Daniel Janus</title>
      <link>https://yosefk.com/cgi-bin/comments.cgi?post=blog/checkedthreads-bug-free-shared-memory-parallelism#comment-1930</link>
      <description><![CDATA[<html><head>
</head><body><p>Just attach a copy of the WTFPL.</p>
<p></p>]]></description>
      <pubDate>Tue, 02 Apr 2013 07:20:00 +0000</pubDate>
      <dc:creator>Daniel Janus</dc:creator>
    </item>
    <item>
      <title>Yossi Kreinin</title>
      <link>https://yosefk.com/cgi-bin/comments.cgi?post=blog/checkedthreads-bug-free-shared-memory-parallelism#comment-1929</link>
      <description><![CDATA[<html><head>
</head><body><p>But all those licenses are less permissive than what I'm aiming for,
actually; they specifically <strong>don't</strong> let you do whatever
you want to with the code – you're obliged to carry the license with the
code and sometimes give credit or whatever. I want it to be like
characters that landed magically into your editor/file system – do
whatever you want to with them; and I don't want to uglify every file
with boilerplate crapola.</p>
<p>Are you seriously saying that I should use an existing license
because you'd actually have to convince your company's lawyers? Does it
work if the license is in the directory but not in each and every
file?</p>
<p></p>]]></description>
      <pubDate>Tue, 02 Apr 2013 07:03:00 +0000</pubDate>
      <dc:creator>Yossi Kreinin</dc:creator>
    </item>
    <item>
      <title>Antti Tuppurainen</title>
      <link>https://yosefk.com/cgi-bin/comments.cgi?post=blog/checkedthreads-bug-free-shared-memory-parallelism#comment-1928</link>
      <description><![CDATA[<html><head>
</head><body><p>It might be good enough for you, but not for any lawyer I've ever
met. :)</p>
<p>Licenses are tricky things and whenever you come up with a new one
with subtly different wording, it's likely to result in undefined
behavior in some jurisdictions around the world. Just like programmers,
lawyers hate undefined behavior.</p>
<p>The MIT license and the new style BSD license give the same effective
guarantees that you're aiming for, but it'll also be a hell of a lot
easier to convince my company's lawyers that we can use and contribute
to software under those licenses.</p>
<p></p>]]></description>
      <pubDate>Tue, 02 Apr 2013 06:54:00 +0000</pubDate>
      <dc:creator>Antti Tuppurainen</dc:creator>
    </item>
    <item>
      <title>Yossi Kreinin</title>
      <link>https://yosefk.com/cgi-bin/comments.cgi?post=blog/checkedthreads-bug-free-shared-memory-parallelism#comment-1927</link>
      <description><![CDATA[<html><head>
</head><body><p>I say that you're free to do anything you want to at no charge, and
without any warranty, in README.md; isn't that good enough?</p>
<p></p>]]></description>
      <pubDate>Tue, 02 Apr 2013 05:58:00 +0000</pubDate>
      <dc:creator>Yossi Kreinin</dc:creator>
    </item>
    <item>
      <title>Random person on the Internet</title>
      <link>https://yosefk.com/cgi-bin/comments.cgi?post=blog/checkedthreads-bug-free-shared-memory-parallelism#comment-1926</link>
      <description><![CDATA[<p>By "no license" you mean public domain? If so, you should state that
explicitly somewhere in the code, since any work is copyrighted by
default by Berne convention. And since public domain is a somewhat
nebulous concept in some countries, you might as well distribute the
code under the 3-clause BSD or MIT license.</p>
<p></p>]]></description>
      <pubDate>Tue, 02 Apr 2013 04:59:00 +0000</pubDate>
      <dc:creator>Random person on the Internet</dc:creator>
    </item>
  </channel>
</rss>
