在宽松内存模型下触发错误尤其是部分存储排序

问题描述

我正在学习轻松的记忆模型,尤其是关于部分存储排序 (PSO)。 许多文献,包括学术论文和 Linux 内核文档,都说下面的模式在 PSO 下是有问题的,因为线程 1 可以重新排序指令,因此 done = 1; 可以在 x = 1; 之前执行。

thread1 {      thread2 {
               if (done) {
x = 1;            if (x==0)
y = 1;                ERROR;
done = 1;         local = y;
}              }

到目前为止一切顺利。看起来很清晰。

然后我决定在真机上重现这个错误。这是 C 中的伪代码片段(忽略一些 pthread API 的详细信息)。

thread 1                                    thread 2
--------                                    --------
ptr = (int *)malloc(sizeof(*ptr));          local_ready = ready;
ready = 1;                                  local_ptr = ptr;
                                            if (local_ready)
                                                local_a = *local_ptr;

thread_main
--------
while(true) {
    ptr = ready = 0;
    pthread_create(&ptr1,thread1);
    pthread_create(&ptr2,thread2);
    pthread_join(ptr1);
    pthread_join(ptr2);
}

所有带有 local_ 前缀的变量都是局部变量,其他的都是全局变量while (true) 循环中的主函数不断将 ptrready 初始化为 0,创建两个线程然后加入它们。我选择 Google Pixel 4XL 作为测试机,因为它配备了 aarch64 cpu(我知道 arm 的内存模型比 PSO 更宽松,但我仍然认为它应该显示出与上述代码片段类似的重新排序行为)。我使用带有 -O0 选项的 Android NDK 工具链交叉编译了该程序。

但它永远不会失败(即 NULL 取消引用)。我再次尝试在两个线程的开头放置更多的指令,将一些随机值写入随机全局变量。我希望它以某种方式增加商店重新订购的机会。但它仍然永远不会失败。

我错过了什么?难道仅仅是因为我运气不好?还是Google Pixel 4XL 的cpu 微架构没有实现store-store reordering?我不认为错误模式不是一个真正的问题,因为大量的学术论文涉及它(甚至 Linux 文档也说它是错误的!)。我确实相信有一种方法可以触发该错误,但我找不到。

这是 /proc/cpuinfo 的第一个条目。触发错误是否需要某种功能

Processor   : AArch64 Processor rev 14 (aarch64)
processor   : 0
BogoMIPS    : 38.00
Features    : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fPHP asimdhp cpuid asimdrdm lrcpc dcpop asimddp
cpu implementer : 0x51
cpu architecture: 8
cpu variant : 0xd
cpu part    : 0x805
cpu revision    : 14

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)