在用户模式和内核之间使用共享内存进行慢速通信 [英] Slow communication using shared memory between user mode and kernel

查看:296
本文介绍了在用户模式和内核之间使用共享内存进行慢速通信的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在Windows内核中运行一个线程,该线程通过共享内存与应用程序通信.一切工作正常,除了由于睡眠循环导致通讯缓慢之外.我一直在研究自旋锁,互斥锁和互锁,但是我真的无法弄清楚这一点.我也考虑过Windows事件,但不知道该事件的性能.请提供一种更快的解决方案,以保持共享内存上的通信可能暗示Windows事件,这将是一个更快的解决方案.

I am running a thread in the Windows kernel communicating with an application over shared memory. Everything is working fine except the communication is slow due to a Sleep loop. I have been investigating spin locks, mutexes and interlocked but can't really figure this one out. I have also considered Windows events but don't know about the performance of that one. Please advice on what would be a faster solution keeping the communication over shared memory possibly suggesting Windows events.

内核代码

typedef struct _SHARED_MEMORY
{
    BOOLEAN mutex;
    CHAR data[BUFFER_SIZE];
} SHARED_MEMORY, *PSHARED_MEMORY;

ZwCreateSection(...)
ZwMapViewOfSection(...)

while (TRUE) {
    if (((PSHARED_MEMORY)SharedSection)->mutex == TRUE) {
      //... do work...
      ((PSHARED_MEMORY)SharedSection)->mutex = FALSE;
    }
    KeDelayExecutionThread(KernelMode, FALSE, &PollingInterval);
}

应用代码

OpenFileMapping(...)
MapViewOfFile(...)

...

RtlCopyMemory(&SM->data, WriteData, Size);
SM->mutex = TRUE;

while (SM->mutex != FALSE) {
    Sleep(1); // Slow and removing it will cause an infinite loop
}

RtlCopyMemory(ReadData, &SM->data, Size);


更新1 目前,这是我想出的最快的解决方案:


UPDATE 1 Currently this is the fastest solution I have come up with:

while(InterlockedCompareExchange(&SM->mutex, FALSE, FALSE));

但是我觉得很有趣,您需要进行交换,并且没有仅用于比较的功能.

However I find it funny that you need to do an exchange and that there is no function for only compare.

推荐答案

您不想使用InterlockedCompareExchange.它会消耗CPU资源,使共享该物理内核的另一个线程可能需要的内核资源饱和,并使内核间总线饱和.

You don't want to use InterlockedCompareExchange. It burns the CPU, saturates core resources that might be needed by another thread sharing that physical core, and can saturate inter-core buses.

您确实需要做两件事:

1)编写一个InterlockedGet函数并使用它.

1) Write an InterlockedGet function and use it.

2)防止循环消耗CPU资源,并防止循环最终解除阻塞时使用所有错误预测的分支之母.

2) Prevent the loop from burning CPU resources and from taking the mother of all mispredicted branches when it finally gets unblocked.

对于1,至少在我上次检查时,此方法可在支持InterlockedCompareExchange的所有编译器上起作用:

For 1, this is known to work on all compilers that support InterlockedCompareExchange, at least last time I checked:

__inline static int InterlockedGet(int *val)
{
    return *((volatile int *)val);
}

对于2,将其作为等待循环的主体:

For 2, put this as the body of the wait loop:

__asm
{
    rep nop
}

对于x86 CPU,此选项用于解决资源饱和和分支预测问题.

For x86 CPUs, this is specified to solve the resource saturation and branch prediction problems.

放在一起:

while ((*(volatile int *) &SM->mutex) != FALSE) {
    __asm
    {
        rep nop
    }
}

如果不合适,请根据需要更改int.

Change int as needed if it's not appropriate.

这篇关于在用户模式和内核之间使用共享内存进行慢速通信的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆