Channels ▼

Clay Breshears

Dr. Dobb's Bloggers

The Tell-Tale Compiler

May 10, 2012

When I taught courses that included modules about achieving parallel correctness, I always recommended that analysis tools should only evaluate unoptimized code. Since you aren't looking for execution speed, yet, in your development, the code can run slower than desired during analysis. The tools I've had the chance to use could better point out source code lines correctly within unoptimized code and unanticipated problems from optimized code modifications were removed from consideration. My parting advice to students about tuning for correctness was: "If your code has errors when running with optimizations but doesn't exhibit those problems after compiling without optimizations, the source of the problem is more likely the compiler (and its optimizations) than something wrong in your code."

More Insights

White Papers

More >>

Reports

More >>

Webcasts

More >>

I want to show one more example of how a compiler can lead to a problem for the unwary programmer. I got this example from Herb Sutter and I thought it was very subtle and clever, so I wanted to share it with you. (Any errors in the explanation or description below are my fault.) Consider the following switch statement on the shared integer x.

if (x > 0 && x < 4) {
  switch (x) { 
    case 1: . . .; break;
    case 2: . . .; break;
    case 3: . . .; break;
  }
  . . .
}

The conditional expression guarantees that the switch will only be executed if the value of x is one of three values: 1, 2, or 3. The compiler is free to optimize the switch into a jump table indexed by the value in x. If, after thread T5 has executed the conditional test and will next enter the "then" block, another thread, T8, updates the value of x to, say, 10, what code does the switch execute? T5 will jump to the code whose address is held in the tenth element of a three-element table. I'm tempted to make reference to the phrase "taking a long walk off a short pier," but I will refrain (even though I guess I just did).

I hope that someone programming a threaded application would not put such a faux pas into their code. An easy solution to the above is to do a protected read of x just before the conditional test and store the results into a temporary local variable. The local variable would be used in the conditional expression and as the selector value in the switch statement. The compiler can implement the jump table and there will be no out of bounds access to the table if the value of x is changed by another thread.

Unfortunately, applications aren't written by a single programmer too often these days. If the programmer of the switch code is unaware that the value of x can be altered by an external thread, the proper protection against the data race won't be implemented. Even if a solo programmer is parallelizing a serial code, she could overlook the interaction of the data race on the switch or even assume that the conditional expression will be able to guard against errant behavior.

One other related potential cause of erroneous execution is out-of-order execution at the instruction level, but I've run out of space.

To summarize from this and my previous post, let me strongly recommend that all possible data races within your code be protected in one fashion or other. Even if you feel that you've buried the race under conditional tests or proof of the data race being benign, the programming language, the compiler, or the hardware may cause application failures. These can be like a loud and steady drum beat that drives you to your wits' end and has you tearing up your code like a man possessed. Well, maybe that's a bit overly dramatic, but tracking down and fixing such "errors" can be maddening.

Related Reading






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.
 


Video