Dennis Zickefoose
Dennis Zickefoose

Reputation: 10969

Loop transformations with potentially shared objects

Consider the following code:

#include <vector>

int sum(const std::vector<int>& v) {
  int count = 0;
  for(int i = 0; i < v.size(); ++i)
    count += v[i];
  return count;
}

For the purposes of this question, assume that is the entire translation unit, that the implementation of std::vector::size and std::vector::operator [] are both available to the compiler.

The compiler can trivially tell that v is not modified within the loop, since there are no function calls except those it has the source to. So it is perfectly reasonable for the compiler to hoist the size() call outside the loop:

for(int i = 0, size = v.size(); i < size; ++i)

However, in a recent answer it was suggested that, since v might be modified by another thread, the compiler is not allowed to perform that optimization. It seems to me, however, that in such a case the function is already tragically broken, so limiting the compiler's options is rather pointless. But I do not understand the new standard's rules regarding sequencing, and how they interact with expression reordering, so perhaps my intuition is wrong.

I am willing to assume that in C++03, that transformation is entirely valid, always. But what of C++11? Obviously, I could throw the function at a compiler and see what happens, but that's a lousy way to check conformance.

Upvotes: 5

Views: 127

Answers (3)

fzhou
fzhou

Reputation: 417

In C++03, thread is a library concept not a language concept. Therefore, it is not a requirement for the compiler to care about threads.

Upvotes: 1

minjang
minjang

Reputation: 9050

By looking only this piece of code, compilers does assume that v is not shared by other threads, and will perform inlining optimizations on size() and operator[]. There is no indication for compilers to judge this vector may be shared. Also, note that STL is not thread-safe.

If your concern is true (i.e., v might be modified by other threads), then the code itself would be wrong since v[i] may have data races. Then, you have to insert a proper critical section.

Upvotes: 2

Oliver Charlesworth
Oliver Charlesworth

Reputation: 272517

As was said in one of the comments to the answer you linked, "the compiler doesn't care about other threads". Unless you have an implementation of std::vector with explicit thread synchronisation constructs, this won't affect optimisation.

Upvotes: 5

Related Questions