Overhead

Suppose there is some non-reentrant function that uses global variables:

int i; void foo(void){ /* modify i */ } 

And then I want to use this function in multi-threaded code, so I can change the code as follows:

 void foo(int i){ /* modify i */ } 

or using the gcc __thread specifier is simpler:

 __thread int i; void foo(void){ /* modify i */ } 

The advantages of the latter is that I do not need to change another code that calls foo ().

My questions are: how much is overhead on in-line storage? Are there any problems with TLS?

Is there some overhead if I change the TLS variable through a separate pointer, for example:

 __thread int i; void foo(void){ int *p = &i; /* modify i using p pointer */ } 

Thanks.

+6
c multithreading thread-local-storage
source share
2 answers

And then, I want to use this function in multi-threaded code, so I can change the code as follows:

 void foo(int i){ /* modify i */ } 

This will certainly not work, since you will only modify copy i . You will need to pass int* or int& if you want the changes to be inserted.

Using TLS, of course, will not lead to significant overhead (either in space or in time) for any user approach that you could use to implement the same functionality. Compilers in practice implement TLS by dynamically allocating the storage “slot” in the global data structure that contains your local stream variable.

When you access a local local thread variable at runtime, there is an additional level of indirection: first, the runtime must access the corresponding local table of thread variables for the current thread, and then extract the value from the table.This selection is performed using the index in the array (which is an operation O (1)).

If you intend to do this:

 __thread int i; void foo(void){ int *p = &i; /* modify i using p pointer */ } 

then there is no need to access i with a pointer. Think of i as a global variable that has a different meaning for each thread executed. You will not need to access the normal global with a pointer to make changes, so there is no need to use a pointer with a local stream variable.

Finally, threaded-local storage is not really intended to store a large number of variables in a stream (there are restrictions, depending on the compiler, on the size of the TLS table), but this is something you can easily get around with: put many variables in a struct and do pointer to struct thread-local.

+10
source share

The only problem I see with TLS is its possible limited size. It depends on the system, so you may run into migration or scaling problems (BTW, TLS may not be available at all on some systems)

+1
source share

All Articles