繁体   English   中英

WinAPI _Interlocked *内在函数,用于char,简称

[英]WinAPI _Interlocked* intrinsic functions for char, short

我需要在char或short上使用_Interlocked ***函数,但是它需要长指针作为输入。 似乎有功能_InterlockedExchange8,我看不到任何文档。 看起来这是未记录的功能。 另外,编译器无法找到_InterlockedAdd8函数。 我将不胜感激有关该功能的任何信息,使用/不使用的建议以及其他解决方案。

更新1

我将尝试简化问题。 我该如何进行这项工作?

struct X
{
    char data;
};

X atomic_exchange(X another)
{
    return _InterlockedExchange( ??? );
}

我看到两种可能的解决方案

  1. 使用_InterlockedExchange8
  2. 长时间投放another ,进行交换并将结果投放回X

第一个显然是不好的解决方案。 第二个看起来更好,但是如何实现呢?

更新2

您如何看待这样的事情?

template <typename T, typename U>
class padded_variable
{
public:
    padded_variable(T v): var(v) {}
    padded_variable(U v): var(*static_cast<T*>(static_cast<void*>(&v))) {}
    U& cast()
    {
        return *static_cast<U*>(static_cast<void*>(&var));
    }
    T& get()
    {
        return var;
    }
private:
    T var;
    char padding[sizeof(U) - sizeof(T)];
};

struct X
{
    char data;
};

template <typename T, int S = sizeof(T)> class var;
template <typename T> class var<T, 1>
{
public:
    var(): data(T()) {}
    T atomic_exchange(T another)
    {
        padded_variable<T, long> xch(another);
        padded_variable<T, long> res(_InterlockedExchange(&data.cast(), xch.cast()));
        return res.get();
    }
private:
    padded_variable<T, long> data;
};

谢谢。

制作8位和16位互锁功能非常容易,但是WinAPI中不包含这些功能的原因是由于IA64可移植性。 如果要支持Win64,则汇编器不能内联,因为MSVC不再支持它。 作为使用MASM64的外部功能单元,它们将不如内联代码或内在函数快,因此,明智的方法是研究促进使用32位和64位原子运算的算法。

互锁的API实现示例: intrin.asm

为什么要使用较小的数据类型? 因此,您可以在一小块存储空间中容纳其中的一堆吗? 这只会导致错误的共享和缓存行争用。

无论您使用锁定算法还是无锁定算法,理想的情况是将数据分成至少128个字节(或CPU上的高速缓存行大小)的块,一次仅由一个线程使用。

好吧,您必须使用可用的功能。 _InterlockedIncrement和`_InterlockedCompareExchange在16位和32位版本中可用(后者在64位版本中也可用),也许其他一些互锁的内在函数也可以在16位版本中使用,但是InterlockedAdd似乎没有是,而且似乎根本没有字节大小的互锁的内在函数/函数。

所以...您需要退后一步,弄清楚如何在没有IntrinsicAdd8情况下解决问题。

无论如何,为什么要使用单个字节? 除非您有充分的理由使用较小的对象,否则请坚持使用int大小的对象。

创建新的答案,因为您的编辑稍微改变了一些内容:

  • 使用_InterlockedExchange8
  • 长时间投放另一个,进行交换并将结果投放回X

第一个根本行不通。 即使该函数存在,它也允许您一次原子更新一个字节。 这意味着整个对象将通过一系列步骤( 不是原子的)进行更新。

除非Xlong尺寸的POD类型,否则第二个也不起作用。 (并且除非它在sizeof(long)边界上对齐,并且除非它与long大小相同)

为了解决此问题,您需要缩小X类型。 首先,当然可以保证是POD类型吗? 否则,您将面临一个完全不同的问题,因为您不能安全地将非POD类型视为原始内存字节。

其次, X可能有什么尺寸? 互锁功能可以处理16、32,并且视情况而定,可以处理64甚至128位的宽度。

这涵盖了您可能遇到的所有情况吗?

如果不是,您可能必须放弃这些原子操作,并选择普通的旧锁。 锁定互斥锁以确保一次只有一个线程触摸这些对象。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM