- 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/
我有两种结构,Header 和Session,它们都符合协议(protocol)TimelineItem。 我有一个 Array 由 TimelineItem 组成,如下所示: [Header1, S
这个问题在这里已经有了答案: Multiple assignment and evaluation order in Python (11 个答案) 关闭 6 年前。 我刚接触python所以想问你
我试图找到一种方法来在 R 中获取 A、A、A、A、B、B、B、B、B 的所有可能的唯一排列的列表。 组合最初被认为是获得解决方案的方法,因此组合的答案。 最佳答案 我认为这就是你所追求的。 @bil
我怎样才能将两个给定的向量混合成一个新的向量,它以交替的顺序保存它们的值。 (f [a a] [b b]) ; > [a b a b] 这是我想到的: (flatten (map vector [:a
这是我的第一个问题,我开始学习Python。之间有区别吗: a, b = b, a + b 和 a = b b = a + b 当您在下面的示例中编写它时,它会显示不同的结果。 def fib(n):
这个问题在这里已经有了答案: Why is there an injected class name? (1 个回答) 12 个月前关闭。 我不知道如何解释: namespace A { struct
我尝试了一些代码来交换 Java 中的两个整数,而不使用第三个变量,使用 XOR。 这是我尝试过的两个交换函数: package lang.numeric; public class SwapVars
假设类 B 扩展类 A,并且我想为 B 声明一个变量。什么更有效?为什么? B b或 A b . 最佳答案 您混淆了两个不同的概念。 class B extends A { } 意味着B 是 A .
我不确定这个问题的标题是什么,这也可能是一个重复的问题。所以请相应地指导。 我是 python 编程的新手。我有这个简单的代码来生成斐波那契数列。 1: def fibo(n): 2: a =
我在谷歌上搜索了有关 dynamic_cast 的内容,我发现显式地将基类对象转换为派生类指针可能是不安全的。但是当我运行一些示例代码来检查它时,我没有收到任何错误。请在下面找到我的代码: class
这个问题在这里已经有了答案: What is this weird colon-member (" : ") syntax in the constructor? (14 个答案) 关闭 8 年前。
在不重现产生非整数值的表达式的情况下实现以下目标的惯用方法是什么(在我的真实情况下,该值是在我不想重现的冗长查询之后计算为百分比的): SELECT * FROM SomeTable WHERE 1/
在析构中,这两个代码的结果确实不同。我不确定为什么。 提示说 const [b,a] = [a,b] 将导致 a,b 的值为 undefined (从左到右的简单分配规则)。我不明白为什么会这样。 l
C++ Templates - The Complete Guide, 2nd Edition介绍max模板: template T max (T a, T b) { // if b < a th
我最近开始学习代码(Java),并根据第 15.17.3 节在 Oracle 网站上查找了模运算符。以下链接: http://docs.oracle.com/javase/specs/jls/se8/
无法理解以下行为。 d1 := &data{1}; 的区别d1 和 d2 := 数据{1}; &d1。两者都是指针,对吧?但他们的行为不同。这里发生了什么 package main import "f
这个问题在这里已经有了答案: How to make loop infinite with "x = y && x != y"? (4 个回答) How can i define variables
在我的程序中,当我调试我的代码时,它似乎在我生成的代码中的某处 X1=['[a,a,a]','[b,b,b]'] 还有我生成的其他地方 X2=[[a,a,a],[b,b,b]] 当我想添加这两个列表然
我试图使用递归将两个整数相乘,并意外编写了这段代码: //the original version int multiply(int a, int b) { if ( !b ) retu
我有一个列表中数字之间所有可能的操作组合: list = ['2','7','8'] 7+8*2 8+7*2 2*8+7 2+8*7 2-8*7 8-2/7 etc 我想知道是否可以说像 ('7*2+
我是一名优秀的程序员,十分优秀!