【问题标题】:std::mutex performance compared to win32 CRITICAL_SECTION与 win32 CRITICAL_SECTION 相比的 std::mutex 性能
【发布时间】:2012-04-17 08:32:00
【问题描述】:

std::mutex 的性能与CRITICAL_SECTION 相比如何?是否符合标准?

我需要轻量级同步对象(不需要是进程间对象)除了std::mutex 之外,是否有任何接近CRITICAL_SECTION 的STL 类?

【问题讨论】:

  • Pedantry: std::mutex 不是 STL 类。也不是任何其他同步对象。
  • @uray:不,它是 C++11 标准库的一部分。 STL 是一种含糊不清的术语,但通常用来指代标准库中的集合、算法、函子和迭代器。例如,std::mutexmemcpystd::ofstream 通常不被视为 STL 的一部分
  • 好的,抱歉,你回复后我的回复已经删除了
  • 如果您担心互斥体的性能,那么您做错了什么。另外:你需要什么样的同步?
  • @zvrba:我不担心,只是想使用最好的可用库来进行简单的同步对象

标签: c++ stl synchronization thread-safety mutex


【解决方案1】:

请在答案末尾查看我的更新,自 Visual Studio 2015 以来情况发生了巨大变化。原始答案如下。

我做了一个非常简单的测试,根据我的测量结果,std::mutexCRITICAL_SECTION 慢了大约 50-70 倍。

std::mutex:       18140574us
CRITICAL_SECTION: 296874us

编辑:经过更多测试,结果表明它取决于线程数(拥塞)和 CPU 内核数。一般std::mutex比较慢,但多少,要看使用情况。以下是更新的测试结果(在配备 Core i5-4258U、Windows 10、Bootcamp 的 MacBook Pro 上测试):

Iterations: 1000000
Thread count: 1
std::mutex:       78132us
CRITICAL_SECTION: 31252us
Thread count: 2
std::mutex:       687538us
CRITICAL_SECTION: 140648us
Thread count: 4
std::mutex:       1031277us
CRITICAL_SECTION: 703180us
Thread count: 8
std::mutex:       86779418us
CRITICAL_SECTION: 1634123us
Thread count: 16
std::mutex:       172916124us
CRITICAL_SECTION: 3390895us

以下是产生此输出的代码。使用 Visual Studio 2012 编译,默认项目设置,Win32 发布配置。请注意,这个测试可能并不完全正确,但它让我在将我的代码从使用 CRITICAL_SECTION 切换到 std::mutex 之前三思而后行。

#include "stdafx.h"
#include <Windows.h>
#include <mutex>
#include <thread>
#include <vector>
#include <chrono>
#include <iostream>

const int g_cRepeatCount = 1000000;
const int g_cThreadCount = 16;

double g_shmem = 8;
std::mutex g_mutex;
CRITICAL_SECTION g_critSec;

void sharedFunc( int i )
{
    if ( i % 2 == 0 )
        g_shmem = sqrt(g_shmem);
    else
        g_shmem *= g_shmem;
}

void threadFuncCritSec() {
    for ( int i = 0; i < g_cRepeatCount; ++i ) {
        EnterCriticalSection( &g_critSec );
        sharedFunc(i);
        LeaveCriticalSection( &g_critSec );
    }
}

void threadFuncMutex() {
    for ( int i = 0; i < g_cRepeatCount; ++i ) {
        g_mutex.lock();
        sharedFunc(i);
        g_mutex.unlock();
    }
}

void testRound(int threadCount)
{
    std::vector<std::thread> threads;

    auto startMutex = std::chrono::high_resolution_clock::now();
    for (int i = 0; i<threadCount; ++i)
        threads.push_back(std::thread( threadFuncMutex ));
    for ( std::thread& thd : threads )
        thd.join();
    auto endMutex = std::chrono::high_resolution_clock::now();

    std::cout << "std::mutex:       ";
    std::cout << std::chrono::duration_cast<std::chrono::microseconds>(endMutex - startMutex).count();
    std::cout << "us \n\r";

    threads.clear();
    auto startCritSec = std::chrono::high_resolution_clock::now();
    for (int i = 0; i<threadCount; ++i)
        threads.push_back(std::thread( threadFuncCritSec ));
    for ( std::thread& thd : threads )
        thd.join();
    auto endCritSec = std::chrono::high_resolution_clock::now();

    std::cout << "CRITICAL_SECTION: ";
    std::cout << std::chrono::duration_cast<std::chrono::microseconds>(endCritSec - startCritSec).count();
    std::cout << "us \n\r";
}

int _tmain(int argc, _TCHAR* argv[]) {
    InitializeCriticalSection( &g_critSec );

    std::cout << "Iterations: " << g_cRepeatCount << "\n\r";

    for (int i = 1; i <= g_cThreadCount; i = i*2) {
        std::cout << "Thread count: " << i << "\n\r";
        testRound(i);
        Sleep(1000);
    }

    DeleteCriticalSection( &g_critSec );

    // Added 10/27/2017 to try to prevent the compiler to completely
    // optimize out the code around g_shmem if it wouldn't be used anywhere.
    std::cout << "Shared variable value: " << g_shmem << std::endl;
    getchar();
    return 0;
}

2017 年 10 月 27 日更新 (1): 一些答案表明这不是一个现实的测试或不代表“现实世界”的场景。没错,这个测试试图测量std::mutex开销,它并不是试图证明对于 99% 的应用程序的差异可以忽略不计。

2017 年 10 月 27 日更新 (2): 自 Visual Studio 2015 (VC140) 以来,情况似乎有利于std::mutex。我使用了 VS2017 IDE,代码与上面完全相同,x64 版本配置,优化被禁用,我只是为每个测试切换了“平台工具集”。结果非常令人惊讶,我真的很好奇 VC140 中挂了什么。

2020 年 2 月 25 日更新 (3): 使用 Visual Studio 2019 (Toolset v142) 重新运行测试,情况依旧:std::mutexCRITICAL_SECTION 快两到三倍。

【讨论】:

  • 希望我们可以做得更好:)
  • I have used 您在下面的代码进行基准测试(我知道,正如另一个答案所指出的那样,争论很激烈,但我对这样的工作台感兴​​趣,可以进行其他讨论)我>。您的代码中的一些挑剔:1. Windows.h 应该是 windows.h,2. 没有必要使用甚至不是标准的 _tmain,3. 您也可以从 main 中删除所有参数,因为您不这样做'不实际使用它们(或者:使用char**而不是非标准的_TCHAR*
  • std::mutex 在 VC 2015 中使用 SRW 锁实现。
  • @Hi-Angel 1. 为什么“windows.h”要小写? Microsoft 始终将此称为“Windows.h”,例如msdn.microsoft.com/en-us/library/windows/desktop/ms682608.aspx。 2. _tmain() 的使用使得代码“Unicode 敏捷”,很有用。它是非标准的,但其余代码也是如此。 3. 使用“char *argv[]”而不是“char **argv”。
  • 使用 wchar_t 绝非毫无意义,它是 Windows 上 Unicode API 的“本机”类型。如果您的应用仅适用于 Windows,那么它是迄今为止最好的选择。将此类代码移植到 Linux 等 UTF-8 平台可能会很痛苦,而 32 位 wchar_t 会使情况变得更糟。
【解决方案2】:

这里waldez的测试不太现实,基本上是模拟100%的争用。一般来说,这正是您在多线程代码中不想要的。下面是一个修改后的测试,它进行了一些共享计算。我用这段代码得到的结果是不同的:

Tasks: 160000
Thread count: 1
std::mutex:       12096ms
CRITICAL_SECTION: 12060ms
Thread count: 2
std::mutex:       5206ms
CRITICAL_SECTION: 5110ms
Thread count: 4
std::mutex:       2643ms
CRITICAL_SECTION: 2625ms
Thread count: 8
std::mutex:       1632ms
CRITICAL_SECTION: 1702ms
Thread count: 12
std::mutex:       1227ms
CRITICAL_SECTION: 1244ms

您可以在这里看到,对我来说(使用 VS2013),std::mutex 和 CRITICAL_SECTION 之间的数字非常接近。请注意,此代码执行固定数量的任务 (160,000),这就是为什么使用更多线程时性能通常会提高的原因。我这里有 12 个核心,所以我停在 12 个核心。

我并不是说这与其他测试相比是对还是错,但它确实强调了时间问题通常是特定于领域的。

#include "stdafx.h"
#include <Windows.h>
#include <mutex>
#include <thread>
#include <vector>
#include <chrono>
#include <iostream>

const int tastCount = 160000;
int numThreads;
const int MAX_THREADS = 16;

double g_shmem = 8;
std::mutex g_mutex;
CRITICAL_SECTION g_critSec;

void sharedFunc(int i, double &data)
{
    for (int j = 0; j < 100; j++)
    {
        if (j % 2 == 0)
            data = sqrt(data);
        else
            data *= data;
    }
}

void threadFuncCritSec() {
    double lMem = 8;
    int iterations = tastCount / numThreads;
    for (int i = 0; i < iterations; ++i) {
        for (int j = 0; j < 100; j++)
            sharedFunc(j, lMem);
        EnterCriticalSection(&g_critSec);
        sharedFunc(i, g_shmem);
        LeaveCriticalSection(&g_critSec);
    }
    printf("results: %f\n", lMem);
}

void threadFuncMutex() {
    double lMem = 8;
    int iterations = tastCount / numThreads;
    for (int i = 0; i < iterations; ++i) {
        for (int j = 0; j < 100; j++)
            sharedFunc(j, lMem);
        g_mutex.lock();
        sharedFunc(i, g_shmem);
        g_mutex.unlock();
    }
    printf("results: %f\n", lMem);
}

void testRound()
{
    std::vector<std::thread> threads;

    auto startMutex = std::chrono::high_resolution_clock::now();
    for (int i = 0; i < numThreads; ++i)
        threads.push_back(std::thread(threadFuncMutex));
    for (std::thread& thd : threads)
        thd.join();
    auto endMutex = std::chrono::high_resolution_clock::now();

    std::cout << "std::mutex:       ";
    std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(endMutex - startMutex).count();
    std::cout << "ms \n\r";

    threads.clear();
    auto startCritSec = std::chrono::high_resolution_clock::now();
    for (int i = 0; i < numThreads; ++i)
        threads.push_back(std::thread(threadFuncCritSec));
    for (std::thread& thd : threads)
        thd.join();
    auto endCritSec = std::chrono::high_resolution_clock::now();

    std::cout << "CRITICAL_SECTION: ";
    std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(endCritSec - startCritSec).count();
    std::cout << "ms \n\r";
}

int _tmain(int argc, _TCHAR* argv[]) {
    InitializeCriticalSection(&g_critSec);

    std::cout << "Tasks: " << tastCount << "\n\r";

    for (numThreads = 1; numThreads <= MAX_THREADS; numThreads = numThreads * 2) {
        if (numThreads == 16)
            numThreads = 12;
        Sleep(100);
        std::cout << "Thread count: " << numThreads << "\n\r";
        testRound();
    }

    DeleteCriticalSection(&g_critSec);
    return 0;
}

【讨论】:

  • 当没有争用时,你会得到相同的结果。如果不是,那么您使用的同步原语已损坏或只是测量不准确。
【解决方案3】:

我在这里搜索 pthread 与关键部分的基准测试,但是,由于我的结果与 waldez 关于该主题的答案不同,我认为分享一下会很有趣。

该代码是@waldez 使用的代码,经过修改以将pthreads 添加到比较中,使用GCC 编译并且没有优化。我的 CPU 是 AMD A8-3530MX。

Windows 7 家庭版:

>a.exe
Iterations: 1000000
Thread count: 1
std::mutex:       46800us
CRITICAL_SECTION: 31200us
pthreads:         31200us
Thread count: 2
std::mutex:       171600us
CRITICAL_SECTION: 218400us
pthreads:         124800us
Thread count: 4
std::mutex:       327600us
CRITICAL_SECTION: 374400us
pthreads:         249600us
Thread count: 8
std::mutex:       967201us
CRITICAL_SECTION: 748801us
pthreads:         717601us
Thread count: 16
std::mutex:       2745604us
CRITICAL_SECTION: 1497602us
pthreads:         1903203us

如您所见,差异在统计误差范围内变化很大——有时 std::mutex 更快,有时则不然。重要的是,我没有观察到原始答案有那么大的差异。

我认为,可能是因为发布答案时,MSVC 编译器不适用于较新的标准,并注意原始答案使用的是 2012 年的版本。

另外,出于好奇,Archlinux 上 Wine 下的相同二进制文件:

$ wine a.exe
fixme:winediag:start_process Wine Staging 2.19 is a testing version containing experimental patches.
fixme:winediag:start_process Please mention your exact version when filing bug reports on winehq.org.
Iterations: 1000000
Thread count: 1
std::mutex:       53810us 
CRITICAL_SECTION: 95165us 
pthreads:         62316us 
Thread count: 2
std::mutex:       604418us 
CRITICAL_SECTION: 1192601us 
pthreads:         688960us 
Thread count: 4
std::mutex:       779817us 
CRITICAL_SECTION: 2476287us 
pthreads:         818022us 
Thread count: 8
std::mutex:       1806607us 
CRITICAL_SECTION: 7246986us 
pthreads:         809566us 
Thread count: 16
std::mutex:       2987472us 
CRITICAL_SECTION: 14740350us 
pthreads:         1453991us

我修改后的 waldez 代码:

#include <math.h>
#include <windows.h>
#include <mutex>
#include <thread>
#include <vector>
#include <chrono>
#include <iostream>
#include <pthread.h>

const int g_cRepeatCount = 1000000;
const int g_cThreadCount = 16;

double g_shmem = 8;
std::mutex g_mutex;
CRITICAL_SECTION g_critSec;
pthread_mutex_t pt_mutex;


void sharedFunc( int i )
{
    if ( i % 2 == 0 )
        g_shmem = sqrt(g_shmem);
    else
        g_shmem *= g_shmem;
}

void threadFuncCritSec() {
    for ( int i = 0; i < g_cRepeatCount; ++i ) {
        EnterCriticalSection( &g_critSec );
        sharedFunc(i);
        LeaveCriticalSection( &g_critSec );
    }
}

void threadFuncMutex() {
    for ( int i = 0; i < g_cRepeatCount; ++i ) {
        g_mutex.lock();
        sharedFunc(i);
        g_mutex.unlock();
    }
}

void threadFuncPTMutex() {
    for ( int i = 0; i < g_cRepeatCount; ++i ) {
        pthread_mutex_lock(&pt_mutex);
        sharedFunc(i);
        pthread_mutex_unlock(&pt_mutex);
    }
}
void testRound(int threadCount)
{
    std::vector<std::thread> threads;

    auto startMutex = std::chrono::high_resolution_clock::now();
    for (int i = 0; i<threadCount; ++i)
        threads.push_back(std::thread( threadFuncMutex ));
    for ( std::thread& thd : threads )
        thd.join();
    auto endMutex = std::chrono::high_resolution_clock::now();

    std::cout << "std::mutex:       ";
    std::cout << std::chrono::duration_cast<std::chrono::microseconds>(endMutex - startMutex).count();
    std::cout << "us \n";
    g_shmem = 0;

    threads.clear();
    auto startCritSec = std::chrono::high_resolution_clock::now();
    for (int i = 0; i<threadCount; ++i)
        threads.push_back(std::thread( threadFuncCritSec ));
    for ( std::thread& thd : threads )
        thd.join();
    auto endCritSec = std::chrono::high_resolution_clock::now();

    std::cout << "CRITICAL_SECTION: ";
    std::cout << std::chrono::duration_cast<std::chrono::microseconds>(endCritSec - startCritSec).count();
    std::cout << "us \n";
    g_shmem = 0;

    threads.clear();
    auto startPThread = std::chrono::high_resolution_clock::now();
    for (int i = 0; i<threadCount; ++i)
        threads.push_back(std::thread( threadFuncPTMutex ));
    for ( std::thread& thd : threads )
        thd.join();
    auto endPThread = std::chrono::high_resolution_clock::now();

    std::cout << "pthreads:         ";
    std::cout << std::chrono::duration_cast<std::chrono::microseconds>(endPThread - startPThread).count();
    std::cout << "us \n";
    g_shmem = 0;
}

int main() {
    InitializeCriticalSection( &g_critSec );
    pthread_mutex_init(&pt_mutex, 0);

    std::cout << "Iterations: " << g_cRepeatCount << "\n";

    for (int i = 1; i <= g_cThreadCount; i = i*2) {
        std::cout << "Thread count: " << i << "\n";
        testRound(i);
        Sleep(1000);
    }

    getchar();
    DeleteCriticalSection( &g_critSec );
    pthread_mutex_destroy(&pt_mutex);
    return 0;
}

【讨论】:

  • 这个测试代码似乎并不能准确地反映任何实际代码的实际作用,也不能衡量同步代码对系统上其他线程的影响或代码在不同步时的行为方式在分支预测缓存中很热。
  • @DavidSchwartz 我知道,see this comment,以及答案。我发布它的唯一原因只是为了表明自 2014 (2012?) 年以来情况发生了变化。
  • @DavidSchwartz 诚然,我本可以发表评论,即使在这种不现实的情况下,现在 std∷mutex 和关键部分的性能也没有差异,但是,人们需要实际数字, 对 :)
【解决方案4】:

我正在使用 Visual Studio 2013。

我在单线程使用中的结果与 waldez 的结果相似:

100 万次锁定/解锁调用:

CRITICAL_SECTION:       19 ms
std::mutex:             48 ms
std::recursive_mutex:   48 ms

微软改变实现的原因是 C++11 兼容性。 C++11 在 std 命名空间中有 4 种互斥锁:

Microsoft std::mutex 和所有其他互斥锁都是关键部分的包装器:

struct _Mtx_internal_imp_t
{   /* Win32 mutex */
    int type; // here MS keeps particular mutex type
    Concurrency::critical_section cs;
    long thread_id;
    int count;
};

对我来说,std::recursive_mutex 应该完全匹配临界区。所以微软应该优化其实现以减少 CPU 和内存。

【讨论】:

  • Win32 临界区在设计上是递归的,所以让mutexrecursive_mutex 使用相同的实现是有意义的(如果非递归互斥体无论如何都是递归的,这并不是真的伤害)。但是,您无法在临界区方面实现timed_mutex(因为没有带有超时参数的TryEnterCriticalSection 这样的东西)。除非实现不兼容,否则它们必须使用键控事件或 Win32 互斥对象。
  • 也许从我的第一条消息中并不清楚,但我写的一样。 Windows 关键部分完全匹配 std::recursive_mutex (并且只有这个互斥锁)。所以特别是 std::recursive_mutex 可以在没有 Windows API 之上的额外数据和逻辑的情况下实现。我也看不出有任何理由将内存中的互斥锁类型作为数据成员。互斥锁的类型在编译时是已知的,可以是模板参数,而不是类成员。
  • 可能的原因是该标准的措辞非常糟糕。它没有说明递归互斥体必须支持被递归调用,但它指出非递归互斥体不得支持它(并且会抛出resource_deadlock_would_occur )。这是调用线程不拥有互斥锁的前提条件。因此,尽管编译器可以使用相同的底层实现(临界区),但为了符合标准,它必须添加额外的代码(和类型成员)以符合这种废话,即使它完全无害。这实际上应该是“未指定的”。
  • 您在谈论 std::mutex (非递归)。我同意当前的 MS 实现需要那些围绕 std::mutex 关键部分的包装器。但是我们不需要那些 std::recursive_mutex 的包装器!
  • 同意,我们需要在这里做得更好。
【解决方案5】:

Waldez 修改为使用 pthread 和 boost::mutex 运行的相同 test program

在 win10 pro(使用 intel i7-7820X 16 核 cpu)上,我从 VS2015 update3 上的 std::mutex 获得更好的结果(甚至从 boost::mutex 获得更好的结果),而不是 CRITICAL_SECTION:

Iterations: 1000000

Thread count: 1
std::mutex:       23403us
boost::mutex:     12574us
CRITICAL_SECTION: 19454us

Thread count: 2
std::mutex:       55031us
boost::mutex:     45263us
CRITICAL_SECTION: 187597us

Thread count: 4
std::mutex:       113964us
boost::mutex:     83699us
CRITICAL_SECTION: 605765us

Thread count: 8
std::mutex:       266091us
boost::mutex:     155265us
CRITICAL_SECTION: 1908491us

Thread count: 16
std::mutex:       633032us
boost::mutex:     300076us
CRITICAL_SECTION: 4015176us

pthreads 的结果是here

#ifdef _WIN32
#include <Windows.h>
#endif
#include <mutex>
#include <boost/thread/mutex.hpp>
#include <thread>
#include <vector>
#include <chrono>
#include <iostream>

const int g_cRepeatCount = 1000000;
const int g_cThreadCount = 16;

double g_shmem = 8;
std::recursive_mutex g_mutex;
boost::mutex g_boostMutex;

void sharedFunc(int i)
{
    if (i % 2 == 0)
        g_shmem = sqrt(g_shmem);
    else
        g_shmem *= g_shmem;
}

#ifdef _WIN32
CRITICAL_SECTION g_critSec;
void threadFuncCritSec()
{
    for (int i = 0; i < g_cRepeatCount; ++i)
    {
        EnterCriticalSection(&g_critSec);
        sharedFunc(i);
        LeaveCriticalSection(&g_critSec);
    }
}
#else
pthread_mutex_t pt_mutex;
void threadFuncPtMutex()
{
    for (int i = 0; i < g_cRepeatCount; ++i) {
        pthread_mutex_lock(&pt_mutex);
        sharedFunc(i);
        pthread_mutex_unlock(&pt_mutex);
    }
}
#endif

void threadFuncMutex()
{
    for (int i = 0; i < g_cRepeatCount; ++i)
    {
        g_mutex.lock();
        sharedFunc(i);
        g_mutex.unlock();
    }
}

void threadFuncBoostMutex()
{
    for (int i = 0; i < g_cRepeatCount; ++i)
    {
        g_boostMutex.lock();
        sharedFunc(i);
        g_boostMutex.unlock();
    }
}

void testRound(int threadCount)
{
    std::vector<std::thread> threads;

    std::cout << "\nThread count: " << threadCount << "\n\r";

    auto startMutex = std::chrono::high_resolution_clock::now();
    for (int i = 0; i < threadCount; ++i)
        threads.push_back(std::thread(threadFuncMutex));
    for (std::thread& thd : threads)
        thd.join();
    threads.clear();
    auto endMutex = std::chrono::high_resolution_clock::now();

    std::cout << "std::mutex:       ";
    std::cout << std::chrono::duration_cast<std::chrono::microseconds>(endMutex - startMutex).count();
    std::cout << "us \n\r";

    auto startBoostMutex = std::chrono::high_resolution_clock::now();
    for (int i = 0; i < threadCount; ++i)
        threads.push_back(std::thread(threadFuncBoostMutex));
    for (std::thread& thd : threads)
        thd.join();
    threads.clear();
    auto endBoostMutex = std::chrono::high_resolution_clock::now();

    std::cout << "boost::mutex:     ";
    std::cout << std::chrono::duration_cast<std::chrono::microseconds>(endBoostMutex - startBoostMutex).count();
    std::cout << "us \n\r";

#ifdef _WIN32
    auto startCritSec = std::chrono::high_resolution_clock::now();
    for (int i = 0; i < threadCount; ++i)
        threads.push_back(std::thread(threadFuncCritSec));
    for (std::thread& thd : threads)
        thd.join();
    threads.clear();
    auto endCritSec = std::chrono::high_resolution_clock::now();

    std::cout << "CRITICAL_SECTION: ";
    std::cout << std::chrono::duration_cast<std::chrono::microseconds>(endCritSec - startCritSec).count();
    std::cout << "us \n\r";
#else
    auto startPThread = std::chrono::high_resolution_clock::now();
    for (int i = 0; i < threadCount; ++i)
        threads.push_back(std::thread(threadFuncPtMutex));
    for (std::thread& thd : threads)
        thd.join();
    threads.clear();
    auto endPThread = std::chrono::high_resolution_clock::now();

    std::cout << "pthreads:         ";
    std::cout << std::chrono::duration_cast<std::chrono::microseconds>(endPThread - startPThread).count();
    std::cout << "us \n";
#endif
}

int main()
{
#ifdef _WIN32
    InitializeCriticalSection(&g_critSec);
#else
    pthread_mutex_init(&pt_mutex, 0);
#endif

    std::cout << "Iterations: " << g_cRepeatCount << "\n\r";

    for (int i = 1; i <= g_cThreadCount; i = i * 2)
    {
        testRound(i);
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }

#ifdef _WIN32
    DeleteCriticalSection(&g_critSec);
#else
    pthread_mutex_destroy(&pt_mutex);
#endif
    if (rand() % 10000 == 1)
    {
        // Added 10/27/2017 to try to prevent the compiler to completely
        // optimize out the code around g_shmem if it wouldn't be used anywhere.
        std::cout << "Shared variable value: " << g_shmem << std::endl;
    }
    return 0;
}

【讨论】:

    【解决方案6】:
    My results for test1
    
    Iterations: 1000000
    Thread count: 1
    std::mutex:      27085us
    CRITICAL_SECTION: 12035us
    Thread count: 2
    std::mutex:      40412us
    CRITICAL_SECTION: 119952us
    Thread count: 4
    std::mutex:      123214us
    CRITICAL_SECTION: 314774us
    Thread count: 8
    std::mutex:      387737us
    CRITICAL_SECTION: 1664506us
    Thread count: 16
    std::mutex:      836901us
    CRITICAL_SECTION: 3837877us
    Shared variable value: 8
    

    用于测试 2

    Tasks: 160000
    Thread count: 1
    results: 8.000000
    std::mutex:       4642ms
    results: 8.000000
    CRITICAL_SECTION: 4588ms
    Thread count: 2
    results: 8.000000
    results: 8.000000
    std::mutex:       2309ms
    results: 8.000000
    results: 8.000000
    CRITICAL_SECTION: 2307ms
    Thread count: 4
    results: 8.000000
    results: 8.000000
    results: 8.000000
    results: 8.000000
    std::mutex:       1169ms
    results: 8.000000
    results: 8.000000
    results: 8.000000
    results: 8.000000
    CRITICAL_SECTION: 1162ms
    Thread count: 8
    results: 8.000000
    results: 8.000000
    results: 8.000000
    results: 8.000000
    results: 8.000000
    results: 8.000000
    results: 8.000000
    results: 8.000000
    std::mutex:       640ms
    results: 8.000000
    results: 8.000000
    results: 8.000000
    results: 8.000000
    results: 8.000000
    results: 8.000000
    results: 8.000000
    results: 8.000000
    CRITICAL_SECTION: 628ms
    Thread count: 12
    results: 8.000000
    results: 8.000000
    results: 8.000000
    results: 8.000000
    results: 8.000000
    results: 8.000000
    results: 8.000000
    results: 8.000000
    results: 8.000000
    results: 8.000000
    results: 8.000000
    results: 8.000000
    std::mutex:       745ms
    results: 8.000000
    results: 8.000000
    results: 8.000000
    results: 8.000000
    results: 8.000000
    results: 8.000000
    results: 8.000000
    results: 8.000000
    results: 8.000000
    results: 8.000000
    results: 8.000000
    results: 8.000000
    CRITICAL_SECTION: 672ms
    

    【讨论】:

      猜你喜欢
      • 2015-04-18
      • 2013-05-27
      • 2020-09-21
      • 1970-01-01
      • 1970-01-01
      • 2010-09-19
      • 1970-01-01
      • 1970-01-01
      • 2017-03-28
      相关资源
      最近更新 更多