Suppose I have an application that may or may not have spawned multiple threads. Is it worth it to protect operations that need synchronization conditionally with a std::mutex a
Underneath your question, David Schwarz commented:
An uncontested mutex is nearly free. The cost of the
if
is probably comparable.
This is blatantly wrong (but a common misconception).
Try running this:
#include
#include
#include
static std::atomic single_threaded(true);
int main(int argc, char *argv[])
{
(void)argv;
if (argc == 100001) { single_threaded = !single_threaded; /* to prevent compiler optimization later */ }
int n = argc == 100000 ? -1 : 10000000;
{
std::mutex mutex;
clock_t const begin = clock();
unsigned int total = 0;
for (int i = 0; i < n; ++i)
{
if (single_threaded)
{
total = ((total << 1) ^ i) + ((total >> 1) & i);
}
else
{
std::lock_guard lock(mutex);
total = ((total << 1) ^ i) + ((total >> 1) & i);
}
}
clock_t const end = clock();
printf("Conditional: %u ms, total = %u\n", (unsigned int)((end - begin) * 1000U / CLOCKS_PER_SEC), total);
}
{
std::mutex mutex;
clock_t const begin = clock();
unsigned int total = 0;
for (int i = 0; i < n; ++i)
{
std::lock_guard lock(mutex);
total = ((total << 1) ^ i) + ((total >> 1) & i);
}
clock_t const end = clock();
printf("Unconditional: %u ms, total = %u\n", (unsigned int)((end - begin) * 1000U / CLOCKS_PER_SEC), total);
}
}
My output? (Visual C++)
Conditional: 24 ms, total = 3684292139
Unconditional: 845 ms, total = 3684292139