gpt4 book ai didi

多处理器系统上的临界区和内存栅栏/屏障

转载 作者:可可西里 更新时间:2023-11-01 10:31:48 25 4
gpt4 key购买 nike

我有一个使用临界区的 Windows DLL(C 语言)。多次调用的特定例程需要在第一次调用时执行一些初始化代码,因此我使用了临界区。但是,由于它被调用了很多次,我试图避免每次调用时都进入该部分的开销。它似乎在工作,但我想知道在具有 x64 操作系统的多处理器(英特尔)系统上运行时考虑内存障碍/栅栏是否存在缺陷?这是精简代码:

int _isInitialized = FALSE;
CRITICAL_SECTION _InitLock = {0};

BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved )
{
ARM_SECTION_BEGIN(ul_reason_for_call)

switch (ul_reason_for_call)
{
case (DLL_PROCESS_ATTACH):
InitializeCriticalSection(&_InitLock);
break;
case (DLL_THREAD_ATTACH):
break;
case (DLL_THREAD_DETACH):
break;
case (DLL_PROCESS_DETACH):
DeleteCriticalSection(&_InitLock);
break;
}
return (TRUE);
}

int myproc(parameters...)
{
if (!_isInitialized) // check first time
{
EnterCriticalSection(&_InitLock);
if (_isInitialized) // check it again
{
LeaveCriticalSection(&_InitLock);
goto initialized;
}
... do stuff ...
_isInitialized = TRUE;
LeaveCriticalSection(&_InitLock);
}
initialized:
... do more stuff ...
return(something)
}

最佳答案

... if there is a flaw considering memory barriers / fences ... ?

使用 volatile

在第二次测试中,代码显然有使用 _isInitialized 过时值的风险。

if (!_isInitialized) {
EnterCriticalSection(&_InitLock);
if (_isInitialized) // Risk

要确保重新读取 _isInitialized,请使用 volatile@JimmyB

// int _isInitialized = FALSE;
volatile int _isInitialized = FALSE;

其他共享数据

_isInitialized 之外的其他数据在 ... do stuff ... 中分配并在后面的 ... do more stuff ... 代码有同样问题的风险,因为优化可能会在第一个 if (!_isInitialized) 之前读取 other_data

代码可以使用volatile other_data。不幸的是,这可能会导致 Not Acceptable 性能拖累。替代方案取决于 stuff 中的内容。

风格

我会将 _isInitialized 设为函数的局部,删除 _ 并避免 goto

int myproc(parameters...) {
static volatile int isInitialized = FALSE;

if (!isInitialized) {
EnterCriticalSection(&_InitLock);
if (!isInitialized) {
// ... do stuff ...
isInitialized = TRUE;
}
LeaveCriticalSection(&_InitLock);
}

// ... do more stuff ...
return(something)
}

关于多处理器系统上的临界区和内存栅栏/屏障,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54032328/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com