Weak vs. Strong Memory Models

本文探讨了内存模型的不同类型,包括弱内存模型、弱数据依赖性排序模型及强内存模型等,并详细解释了各种模型如何影响多核处理器上的锁自由编程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SEP 30, 2012

http://preshing.com/20120930/weak-vs-strong-memory-models/


正文开始--->

Memory reordering有很多种类型,并不是每一种reordering都经常发生。这完全依赖于你所面向的processor,以及你开发时使用的工具。

一个memory model(内存模型)告诉你,对于一个processor或者开发工具,相对于你编写的源码,在运行时可能发生什么类型的memory reordering。记住,仅当使用lock-free编程时memory reordering的影响才会体现出来。

学习memory model也有一小段时间了——绝大部分都是读各种网络文章,然后通过实验验证——我已经有所收获,并把它们分类成了如下的4类。每一种memory model除了完全提供它左边的那个model的所有保证,还能提供更多。我在weak和strong memory model之间画了一条清晰的线,这也符合大部分人使用这些术语的习惯。


图上面的每一种物理设备代表了一种hardware memory model。一个hardware memory model告诉你相对汇编(或者机器)语言代码,在运行期会发生什么样的memory reordering。

在memory reordering上,每一种processor家族都有不同的习性,这些习性仅在多核或者多处理器配置中才能体现出来(multicore or multiprocessor)。现在多核是流行趋势,所以有必要熟悉它们。

对应的,还有software memory model。比如当你使用C/C++或者Java写下可移植的lock-free代码时,通常仅仅需要考虑software memory model。
无论如何,对hardware memory model有一个大概的了解并不难。它可以帮助你解释debug时那些未预期的行为,以及——可能非常重要的——知道有些不正确的代码在某些processor和编译工具下正常运行仅仅是因为运气成分。

Weak Memory Models

对于最弱的那种memory model,可能会碰到在前面代码控制类比中提到过的所有4种memory reordering。任何store和load都可能和其它的store和load重排序,只要没有修改单线程程序的行为。在实际中,reordering可能是因为compiler 对指令的reordering,或者processor自己的memory reordering。

如果一个processor是weak hardware memory model,我们倾向于说它是weakly-ordered或者weak ordering。我们可能也说它有一个relaxed memory model(松弛的内存模型)。对weakly-ordered processor,人们最喜欢举的例子就是DEC Alpha。实在是没有其它的主流processor是weaker ordering的了。

C11和C++11暴露了一个weak software memory model,可能就是因为受到了Alpha的影响。当使用这些语言的底层atomic操作时,你是否真的面向一个类似x86/64的strong processor是无关紧要的。就像我前面证明的,你依然必须指明正确的memory ordering限制,如果只是为了阻止compiler reordering。

Weak With Data Dependency Ordering

虽然Alpha处理器已经不常见了,我们依然有好几种现代CPU家族,继续保持了weak hardware ordering的传统:
> ARM, 移动设备的主流处理器
> PowerPC,这个是Xbox360的主流平台
> Itanium,Linux和HP Server还在支持

这些家族的memory model基本上和Alpha一样弱,除了一个程序员特别关注的细节:它们保持了data dependency ordering。什么意思?这意味着,如果你在C/C++中写A->B,你可以保证读取到的B至少和A一样新。而Alpha则不能保证这个。这里我不想在data dependency ordering上做深入的挖掘,除了提醒一点:Linux RCU机制严重依赖它。

Strong Memory Models

让我们先看看hardware memory model,strong和weak之间的区别到底是什么?实际上对这个问题还有不同的观点(见这个文章:http://herbsutter.com/2012/08/02/strong-and-weak-hardware-memory-models/#comment-5903)。但是我认为80%的情况下,大部分人认为的都是同一回事。因此,我想先提出下面的定义:
—————————————————————————————-
一个strong hardware memory model就是,每一个machine Instruction都潜在的遵守acquire and release语义。因此,当一个CPU core执行一系列的writes时,所有其它CPU core都会按照它们被写入的顺序看到这些值的改变。
—————————————————————————————-
不难想象,现在想象一下对代码控制类比的一个改进,所有提交到共享内存的修改都是有序的(没有StoreStore重排序),从共享内存的读也是有序的(没有LoadLoad重排序),并且所有指令都是按顺序执行的(没有LoadStore重排序)。然而StoreLoad重排序,还是存在的。


基于上面的定义,x86/64 processor家族通常是strongly-ordered。也有一些情况下,x86/64的strong ordering保证会丢失,但是大部分情况下,作为应用程序员,我们可以忽略。一个x86/64 processor确实会乱序执行指令,但是这是硬件实现的细节——重要的是它依然保持了内存指令是有序的,所以在multicore环境中,我们依然认为它是strong-ordered。在历史上,由于evolving sepc的存在,会导致一些小困惑。

显然SPARC processors,在运行在TSO模式下时,是另一个strong hardware ordering的例子。TSO指的是“total store order”,它和我上面给出的定义有一些细微的差别。它意味着,所有core对共享内存的写一直有单一的全局的顺序。x86/64也有这个属性,见Intel x86/64架构规范的卷3,第8.2.3.6-8小结的一些例子。我能说的是,TSO不足以引起对编写底层lock-free的程序员的兴趣,但是它是迈向sequential consistency的一步。

Sequential Consistency

在一个sequential consistent的memory model中,没有memory reordering的存在。好像就是整个程序执行退化成了每个线程之间指令的顺序交叉。特别的前面例子中的r1=r2=0的结果在这里是不可能出现的。

现在,你不可能找到一个在硬件层面保证sequential consistency的多核处理器。然而,历史上有过,那就是1989年的Intel 386。

无论如何,在使用高级程序语言时,sequential consistency仅在software memory model中是令人感兴趣的。在Java5或者更高版本,你可以受用volatile关键字,在C++11,在使用atomic操作时,你可以使用默认的顺序限制:memory_order_seq_cst。如果你这样做,就会限制compiler rereading,并生成相应memory barrier的CPU指令。这样,即使在weakly-ordered 多核设备上,你可以模拟一个sequential consistent的memory model。如果你读过Herlihy&Shavit的The Art of Multiprocessor Programming,一定要注意,它们的例子都假设在一个consequential consistent的software memory model。

Further Details

有关memory model还有其它的很多细节,但是根据我的经验,在编写应用程序级别的lock-free代码时它们用处也不大。比如control dependency,causal consistency,已经不同的内存类型。后面可能还会有更多有关这4种类型的讨论。

如果你真想了解有关processor memory model的更多细节,以及把formal logic当饭吃(形式逻辑),你可以看看剑桥大学的一些工作分享。Paul McKenney对他们的工作和相关工具已经写了一些介绍。
http://www.cl.cam.ac.uk/~pes20/weakmemory/
http://lwn.net/Articles/470681/
(我想一般人就算了)


### Armbian 中命令未找到问题的解决方案 在 Armbian 或其他基于 Debian 的 Linux 发行版中遇到 `command not found` 错误通常是因为缺少相应的软件包或环境配置不正确。以下是针对不同情况的具体处理方法。 #### 1. 更新软件源并安装必要的工具 如果尝试使用某些命令时收到 `command not found` 提示,可能是因为这些命令对应的软件尚未被安装。对于 Armbian 系统而言,默认情况下并不一定预装所有的开发工具和实用程序。因此建议先更新系统的软件库列表: ```bash sudo apt update && sudo apt upgrade -y ``` 这条指令会刷新本地缓存中的可用软件版本信息,并升级已有的软件至最新稳定版[^1]。 #### 2. 安装特定命令所在的软件包 当确认某个具体命令确实不存在于当前环境中时,则需查找其所属的官方软件包名称并通过 APT 包管理器来获取它。例如要解决 `apt-get: command not found` 这样的报错可以这样做: ```bash sudo dpkg --configure -a sudo apt install -f sudo apt install apt-utils ``` 上述操作能够修复潜在依赖关系损坏的情况以及重新安装基本的APT工具集。 而对于像 `vim`, `gcc` 等常用编辑器或编译器类别的缺失,可以直接通过如下方式快速部署它们: ```bash sudo apt install build-essential vim curl git htop tmux zsh jq silversearcher-ag fzf python3-pip nodejs npm yarn docker.io terraform kubectl minikube awscli azure-cli gcloud sdkman-cli rustup dotnet-sdk-go openjdk-17-jdk maven gradle ant cargo go ruby rvm php composer perl cpanminus lua luarocks haskell-stack elixir erlang crystal dmd nim nasm yasm llvm clang bison flex make cmake ninja-build meson pkg-config autoconf automake libtool gettext intltool doxygen graphviz plantuml valgrind strace ltrace tcpdump wireshark ngrep masscan nmap hydra john hashcat sqlmap wpscan nikto dirbuster zaproxy burp-suite-free-edition owasp-zap-baseline security-misc exploitdb metasploit-framework social-engineer-toolkit beef-xss bettercap mitmproxy proxychains privoxy tor polipo squid tinyproxy privoxy torbrowser-launcher tails-installer qubes-os-installation-guide whonix-gateway whonix-workstation hardenedlinux hardening-checklist selinux-apparmor grsecurity paX_tools checksec binwalk radare2 capstone keystone unicornengine angr boofuzz driller fuzzilli jsfunfuzz afl++ libfuzzer honggfuzz syzkaller triton-reil taintbochs s2e klee symbolic-execution concolic-testing binary-ninja idapro ghidra radare2-bindings bindiff patchdiff2 diaphora retdec decompilation reverse-engineering malware-analysis forensics incident-response digital-investigation network-security web-application-security mobile-security cloud-security containerization virtualization sandboxing honeypots pentesting red-teaming blue-teaming purple-teaming threat-hunting vulnerability-assessment risk-management compliance auditing legal issues policy development training education community outreach conferences workshops meetups podcasts blogs books research papers whitepapers case studies best practices guidelines standards frameworks models methodologies tools techniques strategies tactics operations management leadership communication collaboration teamwork project planning organization time management productivity self-improvement personal growth mindset resilience adaptability creativity innovation entrepreneurship business-models startup-strategy market-analysis customer-discovery product-development lean-startup agile-methodology devops continuous-integration delivery pipeline infrastructure-as-code configuration-management monitoring logging alerting performance-tuning scalability reliability availability fault-tolerance disaster-recovery backup-restoration data-protection privacy cybersecurity ethics professional-development career-advice job-search interview-preparation resume-building networking events mentorship coaching peer-support group-study collaborative-learning online-courses tutorials documentation wikis forums mailing-lists slack-discord-channels github-gitlab-bitbucket repositories version-control branching merging pull-request code-review pair-programming test-driven-development behavior-driven-development acceptance-test-driven-development automated-tests unit-tests integration-tests end-to-end-tests property-based-testing mutation-testing static-analysis dynamic-analysis runtime-profiling memory-leak-detection concurrency-debugging race-condition-detection deadlocks-starvation-livelock-prevention deadlock-resolution starvation-fairness scheduling-algorithms resource-allocation deallocation garbage-collection reference-counting smart-pointers weak-reference phantom-reference soft-reference strong-reference finalizer cleanup shutdown-hook lifecycle-hooks initialization-finalization object-oriented-programming functional-programming procedural-programming logic-programming declarative-programming imperative-programming domain-specific-language scripting-language markup-language stylesheet-language query-language template-language macro-language assembly-language low-level-high-level-intermediate languages compilers interpreters transpilers assemblers disassemblers linkers loaders debuggers profilers optimizers analyzers formatters beautifiers linters validators sanitizers obfuscators packagers bundlers minifiers compressors encryptors decryptors signers verifiers authenticators authorizers access-controls permissions roles policies rules constraints conditions expressions statements declarations definitions implementations interfaces inheritance polymorphism encapsulation abstraction composition delegation aggregation association relationships between objects classes structures types primitives generics templates meta-programming reflection introspection annotations attributes metadata serialization deserialization marshalling unmarshalling encoding decoding parsing generating transforming converting translating mapping binding linking referencing dereferencing scoping namespaces modules packages libraries frameworks platforms ecosystems communities organizations institutions enterprises startups non-profits governments agencies universities schools colleges institutes labs centers departments divisions teams groups clubs associations societies foundations
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值