Community
cancel
Showing results for 
Search instead for 
Did you mean: 
smasherprog
Beginner
71 Views

tick_count thread safe?

Hi, I am using the tbb libraries for a project that I am working on and anther programm brought up an excellent question that I could not answer, "how is tick_count thread safe?"

I looked at the code for tick_count::now() and there is nothing special or thread safe about it. How is it thread safe?


For reference, the code is

[bash]inline tick_count tick_count::now() {
    tick_count result;
    LARGE_INTEGER qpcnt;
    QueryPerformanceCounter(&qpcnt);
    result.my_count = qpcnt.QuadPart;
    return result;
}
[/bash]


I took out the ifdefs for each operating system. That doesnt seem thread safe to me, what am I missing?
0 Kudos
7 Replies
Dmitry_Vyukov
Valued Contributor I
71 Views

I guess it's just not thread-safe. What for?
smasherprog
Beginner
71 Views

Well, this is listed in the documentation for the tbb library under the first paragraph for the class tick_count

Quote from the tbb threading documentation

Parallel programming is about speeding up wall clock time, which is the real time that
it takes a program to run. Unfortunately, some of the obvious wall clock timing
routines provided by operating systems do not always work reliably across threads,
because the hardware thread clocks are not synchronized. The library provides
support for timing across threads. The routines are wrappers around operating
services that we have verified as safe to use across threads.



Quote from Intel threading building blocks by James reinders

Unlike some timing interfaces, tick_count is guaranteed to be safe to cuse across all threads. It is based on a common or global clock. It is valid to subtract tick_count valuss that were created by different threads to compute elapsed time.


maybe someone can tell me exaclty what that means in relation to the code? Is the code thread safe across mutliple threads ?
Dmitry_Vyukov
Valued Contributor I
71 Views

Quoting smasherprog
Quote from the tbb threading documentation

Parallel programming is about speeding up wall clock time, which is the real time that
it takes a program to run. Unfortunately, some of the obvious wall clock timing
routines provided by operating systems do not always work reliably across threads,
because the hardware thread clocks are not synchronized. The library provides
support for timing across threads. The routines are wrappers around operating
services that we have verified as safe to use across threads.

Think of the std::string class. It's safe to use std::string objects in different threads (each thread uses it's own set of string objects), but they are not thread-safe in itself in any way, shape or form.

The same with tick_count objects. They provide a "thread-safe timing service" that can be used from a plurality of threads, but each individual object is not thread-safe.

RafSchietekat
Black Belt
71 Views

Now I'm confused... :-)

There seems to be no problem with now(), because it uses a thread-safe library function and is otherwise reentrant.

Maybe the original question can be answered by emphasising that there may be other distributed time references (but what would those be, I wonder?) that are quite accurate when used within their attached set of hardware threads (and therefore within a software thread only if affinity is specified), but that may drift and perhaps even diverge considerably across such sets, like wristwatches that were not recently synchronised. tick_count takes care to pick each environment's way to use a single common reference for now(), so that computing a difference makes sense at all after bringing the values together with proper synchronisation (such as a lock), as you would have to do before being able to subtract ordinary integers computed in different threads. I suppose it would be a more expensive call than getting a hardware thread-specific value, otherwise there would be no use having those as well?

Does that clear up anything?
smasherprog
Beginner
71 Views

First, I have to apologize, my topic and question were not exactly what I meant. I know that the function call tick_count::now() is thread safe, meaning that differeing threads can call the function and there are no possible races that occur, etc.

However, in the documention with tbb, and the book intel threading building blocks, it emphasises how to use tick_count because it is synchronized accross threads as quoted in

Intel Threading Building Blocks
Reference Manual
Document Number 315415-002US

Page 133 first paragraph, second sentence states, "

Unfortunately, some of the obvious wall clock timing routines provided by operating systems do not always work reliably across threads, because the hardware thread clocks are not synchronized. The library provides support for timing across threads. "

Check out the bolded part. If I make the claim to use my product and then say use it because Product A does not have a feature. Is that not implying that the product I have includes that feature? I believe it does.

So, from that sentence, the claim is made that tick_count somehow synchromizes the calls to tick_count::now() so that the result of that call can be used on different threads. Now, I know the results CAN be used on different threads, but I thought that some kind of setafinity is used.

Also In Intel Threading Building Blocks by James Reinders, Page 130,

Unlike some timing interfaces, tick_count is guaranteed to be safe to use across threads. It is based on a common or global clock. It is valid to subtract tick_count values created by different threads to compute elapsed time."

Now, if there is no kind of synchronization, then how is it valid to subtrack tick_count values created by different threads? Is this because the amount of drift is very small and doesnt matter? Or, is it valid because the operation CAN occur, which is like saying, "use Microsoft visual studio as a compiler because you can do addition. of Course you can do addition on their compiler!!. Of course I can subtract two tick_count values, they are just numbers.

I was just a little confused when I found out that tick_count did nothing special :P


Anyway, My question has been answered to my satisifaction thanks.


RafSchietekat
Black Belt
71 Views

I'm still confused. Maybe there's a mix-up between synchronisation of clocks (assuming distributed clocks, each serving a specific set of cores) and synchronisation of data (as in safe access from a different thread)? tick_count claims only the former, so you stilll have to use a lock or similar to reliably access an existing tick_count instance from a different thread.

The name "tick_count" is rather weird in this regard because I would rather expect a tick count to get out of synch than any real-time reference. What would such a possibly diverging real-time reference be, API-wise?
Dmitry_Vyukov
Valued Contributor I
71 Views

I guess they meant known oddities of RDTSC instruction on older processors:
http://en.wikipedia.org/wiki/Time_Stamp_Counter

However, documentation on QueryPerformanceCounter():
http://msdn.microsoft.com/en-us/library/ms644904%28VS.85%29.aspx
also notes that "However, you can get different results on different processors due to bugs in the basic input/output system (BIOS) or the hardware abstraction layer (HAL)."