Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to tell c++ compiler that the object is not changed elsewhere to reach better optimization

I would like to optimize some C++ code. Let have a simplified example:

int DoSomeStuff(const char* data)
{

  while(data != NULL)
  {
    //compute something and use optimization as much as possible
  }
  return result;
}

I know that *data is not changed elsewhere. I mean it's not changed in any other thread, but the compiler cannot know. Is there some way to tell the compiler that data on the pointer are not changed for the entire lifetime of the scope?

UPDATE:

int DoSomeStuff(const volatile char* data)
{

  while(data != NULL)
  {
    //compiler should assume that the data are changed elsewhere
  }
  return result;
}
like image 358
Tomas Kubes Avatar asked Jun 13 '14 11:06

Tomas Kubes


People also ask

Can human being optimize a program better than an automated compiler?

So, with the same degree of knowledge, humans can produce assembly code that is at least as performant as the compilation result. It can probably be even better, as a human developer can optimize for a given task, while the compiler can only apply generic optimizations.

How do compilers optimize code?

Compiler optimization is generally implemented using a sequence of optimizing transformations, algorithms which take a program and transform it to produce a semantically equivalent output program that uses fewer resources or executes faster.

Does const help the compiler?

Only const on an object definition actually makes it immutable. The main point of using const is not to assist the compiler in optimizations but to protect yourself from mistakes.

Why would the C++ compiler try to optimize out function calls for the code that makes them up?

Turning on optimization flags makes the compiler attempt to improve the performance and/or code size at the expense of compilation time and possibly the ability to debug the program. The compiler performs optimization based on the knowledge it has of the program.


2 Answers

1) Will the compiler optimize if the variable is const ?

According to the standard (7.1.6.1):

A pointer or reference to a cv-qualified type need not actually point or refer
to a cv-qualified object, but it is treated as if it does

So I understand it as: the compiler will optimize all access to a const qualified variable as if it really was a const data and could not be modified by a path to a non const variable.

2) Will the compiler not optimize to protect inter-thread access ?

According to the standard (1.10):

The execution of a program contains a data race if it contains two conflicting
actions in different threads, at least one of which is not atomic, and neither
happens before the other. Any such data race results in undefined behavior.

A conflicting action is defined as:

Two expression evaluations conflict if one of them modifies a memory location
(1.7) and the other one accesses or modifies the same memory location.

The happens-before relationship is complex but as I understand it, unless you explicitly used atomic operations (or mutexes) in your code, accessing the same variable from two threads (one writing, another one reading/writing) is undefined behavior. This case being undefined behavior I don't think the compiler will protect you, and it is free to optimize.

3) Volatile ?

Volatile is designed to prevent optimization (7.1.6.1):

volatile is a hint to the implementation to avoid aggressive optimization
involving the object because the value of the object might be changed by means
undetectable by an implementation

Think about a memory mapped I/O register (like a special input port). Even though you cannot write it (because your hardware implementation is read-only), you cannot optimiza your read accesses (because they will return a different byte each time). This special I/O port may be a temperature sensor for instance.

like image 163
fjardon Avatar answered Nov 14 '22 22:11

fjardon


The compiler is already allowed to assume *data is not modified by another thread. Modifying data in one thread and accessing it in another thread without proper synchronisation is Undefined Behaviour. The compiler is totally free to do anything at all with a program that contains undefined behaviour.

like image 24
n. 1.8e9-where's-my-share m. Avatar answered Nov 14 '22 21:11

n. 1.8e9-where's-my-share m.