Community
cancel
Showing results for 
Search instead for 
Did you mean: 
michaelnikelsky1
Beginner
78 Views

How to use thread local storage

Hi,

I am needing some per thread scratchmemory where I can store some temporary values. This scratchmemory needs to be fairly large (several MB or so), so I dont want to allocate that on the stack.

I guess this is what thread local storage is for but I have some trouble understanding how I can use the TBB combinable classes for it and which exactly I would need.

Are there any examples on how to use it? Assuming I have a main thread that executes several tasks, how and when do I allocate the memory? How do I access the memory? Do I need memory per Task-Type or can I have something like a global scratchmemory my different tasks can access to store temporary values?

Any help would be welcome
Michael
0 Kudos
5 Replies
jimdempseyatthecove
Black Belt
78 Views

Michael,

This is one way to do it.

struct YourStruct_t
{
... // things you want thread private
};

__declspec( thread )
YourStruct_t* pYourStruct = NULL;

// called by each thread sometime before first use
void YourThreadInit()
{
if(!pYourStruct) pYourStruct = new YourStruct_tl
}

Note, you can have individual items with __declspec( thread ). I prefer to use an encapsulation within a stucture.
** generally you want to deferr the ctor until running in thread context **

Jim Dempsey
michaelnikelsky1
Beginner
78 Views

Hi,

I need to do this with the TBB so I have essentially no info about threads, just tasks. Or can I just call

void YourThreadInit()
{
if(!pYourStruct) pYourStruct = new YourStruct_tl
}

inside a task?

Michael
jimdempseyatthecove
Black Belt
78 Views

Yes, you simply call that within your task.

__declspec( thread )
YourStruct_t pYourStruct = NULL;

Creates a thread private pointer named pYourStruct and initialized to NULL.
Then whenever your code dereferences the pYourStruct, it generates some additional code to obtain it from a thread private area. You can see this code in a dissassembly window.

Each thread will have a private copy of the pointer (and everything else you decorate with __declspec( thread )).
Each thread that uses this poiner must initialize the pointer and any corrisponding allocations within the struct.

You can use this technique with OpenMP theads, PThreads, Cilk++ threads, etc...

***
g++ uses a different syntax to mark threads private

#if defined(__GNUC__)
#define __TLS__ __thread
#else
#define __TLS__ __declspec( thread )
#endif
...
__TLS__ YourStruct_t* pYourStruct = NULL;

Jim Dempsey
Alexey_K_Intel3
Employee
78 Views

TBB Reference contains an example how to use enumerable_thread_specific template class. combinable template class can be used in a similar manner.

MSDN contains a page with an example of using Concurrency::combinable: http://msdn.microsoft.com/en-us/library/dd728079.aspx. Since TBB implementation is compatible, it should work with TBB as well.
michaelnikelsky1
Beginner
78 Views

Thanks to you both, I will try that.
Reply