Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 796
Dennis Zickefoose Avatar asked Nov 15 '11 17:11

Dennis Zickefoose


1 Answers

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.

like image 53
Oliver Charlesworth Avatar answered Sep 28 '22 15:09

Oliver Charlesworth