- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
考虑 x86 CPU 上的单次内存访问(单次读取或单次写入,而不是读取+写入)SSE 指令。该指令正在访问 16 字节(128 位)的内存,并且访问的内存位置与 16 字节对齐。
文档“英特尔® 64 位架构内存订购白皮书”指出,对于“读取或写入地址在 8 字节边界上对齐的四字(8 字节)的指令”而言,内存操作似乎作为单个内存访问执行,无论内存类型。
问题:是否存在 Intel/AMD/etc x86 CPU 可以保证读取或写入与 16 字节边界对齐的 16 字节(128 位)作为单个内存访问执行? 是这样,它是哪种特定类型的 CPU(Core2/Atom/K8/Phenom/...)?如果您对此问题提供答案(是/否),还请注明方法用于确定答案 - PDF 文档查找、蛮力测试、数学证明或用于确定答案的任何其他方法。
此问题涉及 http://research.swtch.com/2010/02/off-to-races.html 等问题。
更新:
我用 C 语言创建了一个简单的测试程序,您可以在计算机上运行它。请在您的 Phenom、Athlon、Bobcat、Core2、Atom、Sandy Bridge 或您碰巧拥有的任何支持 SSE2 的 CPU 上编译并运行它。谢谢。
// Compile with:
// gcc -o a a.c -pthread -msse2 -std=c99 -Wall -O2
//
// Make sure you have at least two physical CPU cores or hyper-threading.
#include <pthread.h>
#include <emmintrin.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
typedef int v4si __attribute__ ((vector_size (16)));
volatile v4si x;
unsigned n1[16] __attribute__((aligned(64)));
unsigned n2[16] __attribute__((aligned(64)));
void* thread1(void *arg) {
for (int i=0; i<100*1000*1000; i++) {
int mask = _mm_movemask_ps((__m128)x);
n1[mask]++;
x = (v4si){0,0,0,0};
}
return NULL;
}
void* thread2(void *arg) {
for (int i=0; i<100*1000*1000; i++) {
int mask = _mm_movemask_ps((__m128)x);
n2[mask]++;
x = (v4si){-1,-1,-1,-1};
}
return NULL;
}
int main() {
// Check memory alignment
if ( (((uintptr_t)&x) & 0x0f) != 0 )
abort();
memset(n1, 0, sizeof(n1));
memset(n2, 0, sizeof(n2));
pthread_t t1, t2;
pthread_create(&t1, NULL, thread1, NULL);
pthread_create(&t2, NULL, thread2, NULL);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
for (unsigned i=0; i<16; i++) {
for (int j=3; j>=0; j--)
printf("%d", (i>>j)&1);
printf(" %10u %10u", n1[i], n2[i]);
if(i>0 && i<0x0f) {
if(n1[i] || n2[i])
printf(" Not a single memory access!");
}
printf("\n");
}
return 0;
}
0000 96905702 10512
0001 0 0
0010 0 0
0011 22 12924 Not a single memory access!
0100 0 0
0101 0 0
0110 0 0
0111 0 0
1000 0 0
1001 0 0
1010 0 0
1011 0 0
1100 3092557 1175 Not a single memory access!
1101 0 0
1110 0 0
1111 1719 99975389
最佳答案
Erik Rigtorp 对最近的 Intel 和 AMD CPU 进行了一些实验测试,以寻找撕裂。结果在 https://rigtorp.se/isatomic/ .请记住,没有关于这种行为的文档或保证,IDK 是否有可能使用这种 CPU 的自定义多插槽机器比他测试的机器具有更少的原子性。但是在当前的 x86 CPU(不是 K10)上,对齐加载/存储的 SIMD 原子性只是随着缓存和 L1d 缓存之间的数据路径宽度而缩放。
仅限 x86 ISA guarantees atomicity for things up to 8B ,因此实现可以像 Pentium III/Pentium M/Core Duo 那样自由地实现 SSE/AVX 支持:内部数据以 64 位的一半处理。一个 128 位存储作为两个 64 位存储完成。在 Yonah 微架构 (Core Duo) 中,进出缓存的数据路径只有 64b 宽。 (来源:Agner Fog's microarch doc)。
最近的实现在内部确实具有更宽的数据路径,并将 128b 指令作为单个操作处理。 Core 2 Duo (conroe/merom) 是第一个具有 128b 数据路径的 Intel P6 后裔微架构。 (关于 P4 的 IDK,但幸运的是它已经足够老了,完全无关紧要。)
这就是为什么 OP 发现 128b ops 在 Intel Core Duo (Yonah) 上不是原子的,但其他海报发现它们在后来的 Intel 设计中是原子的,从 Core 2 (Merom) 开始。
The diagrams on this Realworldtech writeup about Merom vs. Yonah显示 Merom(和 P4)中 ALU 和 L1 数据缓存之间的 128 位路径,而低功耗 Yonah 具有 64 位数据路径。在所有 3 种设计中,L1 和 L2 高速缓存之间的数据路径均为 256b。
数据路径宽度的下一个跳跃来自英特尔的 Haswell, featuring 256b (32B) AVX/AVX2 loads/stores ,以及 L1 和 L2 缓存之间的 64Byte 路径。我希望 256b 加载/存储在 Haswell、Broadwell 和 Skylake 中是原子的,但我没有要测试的。我忘记了 Skylake 是否再次拓宽了在 Skylake-EP(服务器版本)中为 AVX512 做准备的路径,或者 AVX512 的初始实现是否会像 SnB/IvB 的 AVX,并且有 512b 加载/存储占用加载/存储端口2个周期。
正如 janneb 在他出色的实验答案中指出的那样,多核系统中套接字之间的缓存一致性协议(protocol)可能比您在共享最后一级缓存 CPU 中获得的协议(protocol)更窄。对宽负载/存储的原子性没有架构要求,因此设计人员可以自由地将它们在套接字内设为原子,但如果方便,则在套接字之间设为非原子。 IDK 对于 AMD 的 Bulldozer 系列或 Intel 的套接字间逻辑数据路径有多宽。 (我说“逻辑”,因为即使数据以较小的 block 传输,它也可能在完全接收之前不会修改缓存行。)
查找有关 AMD CPU 的类似文章应该可以得出关于 128b 操作是否是原子的合理结论。仅检查指令表会有所帮助:
K8 解码 movaps reg, [mem]
到 2 m-ops,而 K10 和推土机系列将其解码为 1 m-ops。 AMD 的低功耗 bobcat 将其解码为 2 ops,而 jaguar 将 128b movaps 解码为 1 m-op。 (它支持类似于推土机系列 CPU 的 AVX1:256b insns(甚至 ALU 操作)被拆分为两个 128b 操作。英特尔 SnB 仅拆分 256b 加载/存储,同时具有全宽 ALU。)
janneb 的 Opteron 2435 是 6-core Istanbul CPU, which is part of the K10 family ,所以这个单操作 -> 原子结论在单个套接字中看起来是准确的。
英特尔 Silvermont 使用单个 uop 进行 128b 加载/存储,每个时钟的吞吐量为 1。这与整数加载/存储相同,因此很可能是原子的。
关于concurrency - SSE指令: which CPUs can do atomic 16B memory operations?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7646018/
我正在编写一个使用“top”命令的脚本。 当我使用 top 时,我可以看到平均 CPU 使用率: Cpu(s): 41.9%us, 9.4%sy, 0.0%ni, 48.8%id, 0.0%wa, 0
我正在使用 gRPC 库并且有很多“无法处理热插拔 CPU”日志。我很困惑,因为此日志的条件 ( https://github.com/grpc/grpc/blob/master/src/core/l
我有大量数据文件需要通过函数 A 处理。假设有 1000 个文件,每个文件的每个处理时间不到 15 分钟,内存为 6GB。我的电脑有 32GB 和 8 个 CPU,所以为了安全起见,我一次最多可以使用
我是分布式tensorflow的新手,正在寻找一个在CPU上进行同步训练的好例子。 我已经尝试过Distributed Tensorflow Example,它可以在1个参数服务器(1个具有1个CPU
首先我在独立模式下运行! 我一直试图找到任何配置,但我还没有找到任何相关信息。 在 Spark 中有一些配置可以让你限制在每个从属中使用的 CPU 数量: SPARK_WORKER_CORES(工作人
我知道在对称多处理器 (SMP) 系统中,由于每个内核中的单独缓存,可能会发生错误共享,对于以下代码:http://software.intel.com/en-us/articles/avoiding
我正在使用 appjs 开发一个聊天应用程序,该应用程序使用 node.js 作为平台。我一直在检测计算机何时处于空闲状态(当用户离开计算机或不使用计算机时)。 node.js中有一个os模 bl
当您使用命令运行 perf 实用程序时,您获得的输出行之一如下所示: 2.088031 task-clock (msec) # 0.700 CPUs
在我的 mapPartition 部分,有多线程工作要做,我使用线程池并希望并行运行任务。但我无法区分这两个参数。 我想我可以设置 --executor-cores 到 5,我在我的任务中运行了 4
考虑 x86 CPU 上的单次内存访问(单次读取或单次写入,而不是读取+写入)SSE 指令。该指令正在访问 16 字节(128 位)的内存,并且访问的内存位置与 16 字节对齐。 文档“英特尔® 64
从 eclipse 内部启动 android 模拟器时出现问题。我收到错误消息:PANIC:缺少“x86_64”CPUS 的模拟器引擎程序 我可以从命令行启动模拟器: ./emulator64-x86
我正在尝试将我的微型计算引擎从 us-central2-a 移至 us-central1-a,因为 Google 将在一周内对第一个区域进行维护。我正在我的 Windows 计算机上通过 Cygwin
我遇到了与以下链接中提到的相同的问题。但是这个问题已被搁置,我仍在寻求解决方案。 https://stackoverflow.com/questions/27146511/panic-missing-
简单的多线程 c++11 程序,其中所有线程在紧密循环中锁定相同的互斥量。 当它使用8个线程时(作为逻辑cpu的数量)可以达到500万锁/秒 但是只添加一个额外的线程 - 性能会下降到 200,000
我知道 JVM 内存模型是为 CPU 的最低公分母设计的,因此它必须假设 JVM 可以在其上运行的 cpu 的最弱模型(例如 ARM)。 现在,考虑到 x64 具有相当强大的内存模型,假设我知道我的程
在 linux 内核 smp 中,pen_release 标识符用于启动辅助 cpu,我还发现它也在其他地方使用。 我已经在 sysdump 中检查了它的值,还尝试通过 lauterbach 设置来理
我需要更新一些旧代码以使用最新版本的 OpenMPI,但我对新的 --map-by 系统感到非常困惑。特别是,我不确定如何替换 --cpus-per-proc N。 几个网站建议使用 --map-by
sbatch 中使用的术语手册页可能有点困惑。因此,我想确保我正确设置了选项。假设我有一个任务要在具有 N 个线程的单个节点上运行。我假设我会使用 --nodes=1 是否正确?和 --ntasks=
我想使用以下资源分配来运行两个容器: 容器“C1”:保留 cpu1,共享 cpu2(具有 20 个 cpu 份额) 容器“C2”:保留 cpu3,共享 cpu2(具有 80 个 cpu 份额) 如果我
当 NMI 看门狗被“禁用”时,它仍然喋喋不休。 有谁知道这些消息的文档在哪里?我想看看到底发生了什么。 例如,验证其已禁用: $ cat /proc/sys/kernel/nmi_watchdog
我是一名优秀的程序员,十分优秀!