相关疑难解决方法(0)

为什么编译器在初始化volatile数组时会生成这样的代码?

我有以下程序启用x86处理器标志寄存器中的对齐检查(AC)位,以捕获未对齐的内存访问.然后程序声明两个volatile变量:

#include <assert.h>

int main(void)
{
    #ifndef NOASM
    __asm__(
        "pushf\n"
        "orl $(1<<18),(%esp)\n"
        "popf\n"
    );
    #endif

    volatile unsigned char foo[] = { 1, 2, 3, 4, 5, 6 };
    volatile unsigned int bar = 0xaa;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

如果我编译它,最初生成的代码会做一些显而易见的事情,比如设置堆栈并通过将值1,2,3,4,5,6移动到堆栈上来创建字符数组:

/tmp ? gcc test3.c -m32
/tmp ? gdb ./a.out
(gdb) disassemble main
   0x0804843d <+0>: push   %ebp
   0x0804843e <+1>: mov    %esp,%ebp
   0x08048440 <+3>: and    $0xfffffff0,%esp
   0x08048443 <+6>: sub    $0x20,%esp
   0x08048446 <+9>: mov    %gs:0x14,%eax
   0x0804844c <+15>:    mov    %eax,0x1c(%esp)
   0x08048450 <+19>:    xor    %eax,%eax
   0x08048452 <+21>: …
Run Code Online (Sandbox Code Playgroud)

c assembly compilation

11
推荐指数
1
解决办法
368
查看次数

是x86 CMPXCHG原子,如果是这样,为什么需要LOCK?

Intel的文档

该指令可以与LOCK前缀一起使用,以允许指令以原子方式执行.

我的问题是

  1. 可以CMPXCHG用内存地址操作吗?从文档看来似乎没有,但任何人都可以确认只能在寄存器中使用实际的VALUE,而不是内存地址吗?

  2. 如果CMPXCHG不是原子级和高级语言级CAS必须通过LOCK CMPXCHG(带LOCK前缀)来实现,那么引入这样一条指令的目的是什么?

concurrency x86 compare-and-swap

10
推荐指数
2
解决办法
8761
查看次数

AtomicCmpExchange在所有平台上都可靠吗?

我找不到AtomicCmpExchange(似乎隐藏)的实现,所以我不知道它的作用.

AtomicCmpExchange在所有平台上可靠吗?它是如何在内部实施的?它是否使用类似临界区的东西?

我有这种情况:

MainThread:

Target := 1;
Run Code Online (Sandbox Code Playgroud)

线程1:

x := AtomicCmpExchange(Target, 0, 0);
Run Code Online (Sandbox Code Playgroud)

线程2:

Target := 2;
Run Code Online (Sandbox Code Playgroud)

Thread3:

Target := 3;
Run Code Online (Sandbox Code Playgroud)

x永远是一个整数1,2或3,或可能是别的东西吗?我的意思是,即使AtomicCmpExchange(Target, 0, 0)未能交换该值,它是否返回一个"有效"整数(我的意思是,不是半读取整数,例如,如果另一个线程已经开始写入该值的一半)?

我想避免使用临界区,我需要最大速度.

delphi

10
推荐指数
1
解决办法
584
查看次数

InterlockedExchange和内存对齐

我很困惑,微软表示InterlockedExchange需要内存对齐,但是,英特尔文档说LOCK不需要内存对齐.我错过了什么,或者其他什么?谢谢

来自Microsoft MSDN Library

Platform SDK:DLL,进程和线程InterlockedExchange

Target参数指向的变量必须在32位边界上对齐 ; 否则,此函数将在多处理器x86系统和任何非x86系统上出现不可预测的行为.

来自英特尔软件开发人员手册;

  • LOCK指令在执行伴随指令期间使处理器的LOCK#信号有效(将指令转换为原子指令).在多处理器环境中,LOCK#信号确保处理器在信号被置位时独占使用任何共享存储器.

    LOCK前缀的完整性不受存储器字段对齐的影响. 对于任意未对齐的字段,观察到存储器锁定.

  • P6中的内存排序和更新的处理器系列

    锁定的指令有一个总订单.

  • 软件控制总线锁定

    总线锁的完整性不受存储器字段对齐的影响.遵循LOCK语义以获得更新整个操作数所需的多个总线周期.但是,建议锁定访问在其自然边界上对齐,以获得更好的系统性能:•8位访问的任何边界(锁定或其他).•锁定字访问的16位边界.•锁定双字访问的32位边界.•锁定四字访问的64位边界.

x86 winapi multithreading interlocked

8
推荐指数
2
解决办法
2331
查看次数

为什么memory_order_relaxed在x86上使用原子(锁定前缀)指令?

在Visual C++ 2013上,当我编译以下代码时

#include <atomic>

int main()
{
    std::atomic<int> v(2);
    return v.fetch_add(1, std::memory_order_relaxed);
}
Run Code Online (Sandbox Code Playgroud)

我在x86上找回了以下程序集:

51               push        ecx  
B8 02 00 00 00   mov         eax,2 
8D 0C 24         lea         ecx,[esp] 
87 01            xchg        eax,dword ptr [ecx] 
B8 01 00 00 00   mov         eax,1 
F0 0F C1 01      lock xadd   dword ptr [ecx],eax 
59               pop         ecx  
C3               ret              
Run Code Online (Sandbox Code Playgroud)

在x64上类似:

B8 02 00 00 00    mov         eax,2 
87 44 24 08       xchg        eax,dword ptr [rsp+8] 
B8 01 00 00 00    mov         eax,1 …
Run Code Online (Sandbox Code Playgroud)

c++ x86 atomic visual-c++ relaxed-atomics

6
推荐指数
1
解决办法
1651
查看次数

如果`atomic &lt;T&gt;`是无锁的,并且大小与`T`相同,那么内存布局是否相同?

这里这个问题表明,std::atomic<T>普遍认为有大小相同T,而事实上,这似乎是对GCC,铛,和MSVC在x86,x64和ARM的情况。

std::atomic<T>某个类型始终无锁的实现中T,是否保证其内存布局与的内存布局相同T?是否还有其他特殊要求std::atomic,例如对齐?

c++ atomic abi memory-layout c++11

4
推荐指数
1
解决办法
82
查看次数

如果 8 字节由不同线程写入,是否可以保证在现代英特尔 x86 上读取 8 字节?

struct Data {
    double a;
    double b;
    double c;
};
Run Code Online (Sandbox Code Playgroud)

如果在不同的线程上读取,但只有一个其他线程正在写入 a、b、c 中的每一个,那么读取每个双精度值是否正常?

如果我确保Data对齐,会出现什么情况?

struct Data {double a,b,c; } __attribute__((aligned(64));
Run Code Online (Sandbox Code Playgroud)

这将确保 a,b,c 中的每一个都对齐到 64,64+8, 64+16... 所以总是对齐到 8*8=64 位边界。

这个问题对原子 x86 指令的对齐要求及其答案让我认为Data::a/b/c从另一个线程写入并同时读取它们而不使用std::atomic.

是的,我知道std::atomic会解决这个问题,但这不是问题。

c++ x86 multithreading atomic

4
推荐指数
1
解决办法
209
查看次数