- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
gcc docs谈谈读预取和写预取之间的区别。技术上有什么区别?
最佳答案
在 CPU 级别,软件预取(与硬件本身触发的预取相反)是一种向 CPU 提示某行即将被访问的便捷方式,您希望提前预取它以保存延迟。
如果访问是一个简单的读取,你会想要一个常规的预取,它的行为类似于从内存中的正常加载(除了在它未命中时不阻塞 CPU,在地址错误时不出错,以及各种其他好处,具体取决于微架构)。
但是,如果您打算写入该行,并且它也存在于另一个内核中,那么简单的读取操作是不够的。这是由于基于 MESI 的缓存处理协议(protocol)。核心必须在修改某行之前拥有该行的所有权,以保持一致性(如果同一行在多个核心中被修改,您将无法确保这些更改的正确顺序,甚至可能会丢失其中一些,这在普通 WB 内存类型上是不允许的)。相反,写入操作将从获取线路的所有权开始,并从可能持有副本的任何其他核心/套接字中窥探它。只有这样才能进行写入。读取操作(需求或预取)会使其他内核中的行处于共享状态,如果该行被许多内核多次读取,这很好,但如果您的内核稍后写入它,则无济于事。
为了允许对稍后写入的行进行有用的预取,大多数 CPU 公司都支持用于写入的特殊预取。在 x86 中,Intel 和 AMD 都支持 prefetchW 指令,它应该具有写入的效果(即 - 获得一行的唯一所有权,并使任何其他副本无效)。请注意,并非所有 CPU 都支持它(即使在同一个系列中,也不是所有世代都支持它),并且并非所有编译器版本都支持它。
这是一个示例(使用 gcc 4.8.2)- 请注意,您需要在此处明确启用它-
#include <emmintrin.h>
int main() {
long long int a[100];
__builtin_prefetch (&a[0], 0, 0);
__builtin_prefetch (&a[16], 0, 1);
__builtin_prefetch (&a[32], 0, 2);
__builtin_prefetch (&a[48], 0, 3);
__builtin_prefetch (&a[64], 1, 0);
return 0;
}
使用 gcc -O3 -mprfchw prefetchw.c -c
编译,:
0000000000000000 <main>:
0: 48 81 ec b0 02 00 00 sub $0x2b0,%rsp
7: 48 8d 44 24 88 lea -0x78(%rsp),%rax
c: 0f 18 00 prefetchnta (%rax)
f: 0f 18 98 80 00 00 00 prefetcht2 0x80(%rax)
16: 0f 18 90 00 01 00 00 prefetcht1 0x100(%rax)
1d: 0f 18 88 80 01 00 00 prefetcht0 0x180(%rax)
24: 0f 0d 88 00 02 00 00 prefetchw 0x200(%rax)
2b: 31 c0 xor %eax,%eax
2d: 48 81 c4 b0 02 00 00 add $0x2b0,%rsp
34: c3 retq
如果您使用第二个参数,您会注意到 prefetchW 会忽略提示级别,因为它不支持时间级别提示。顺便说一句,如果你删除 -mprfchw 标志,gcc 会将其转换为正常的读取预取(我没有尝试过不同的 -march/mattr 设置,也许其中一些也包括它)。
关于c - 读取或写入预取之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30003361/
我在字符串中有一个大词。例子白 Wine 额外优惠。 我想在第一行使用“White”,在第二行使用“wine extra offer”。使用下面的代码: string value="White win
我想在无符号中执行一些算术运算,需要取负整数的绝对值,比如 do_some_arithmetic_in_unsigned_mode(int some_signed_value) { unsign
我正在努力使用 data.table 来总结向量函数的结果,这在 ddply 中很容易。 问题 1:使用带有矢量输出的(昂贵的)函数聚合 dt dt[ , as.list(quantile(x)),
我有两个分数列表; 说 A = [ 1/212, 5/212, 3/212, ... ] 和 B = [ 4/143, 7/143, 2/143, ... ] . 如果我们定义 A' = a[0] *
我已经使用 numpy 从 csv 文件中获取数据。 numpy 数组的尺寸为:100*20。我如何取列的平均值(比如 col 3,5,8)并用包含这 3 个 cols 平均值的新列替换它们 如果
在 Rust 中取任意数的 n 次根的最佳方法是什么?例如,num crate 只允许取整数类型的第 n 个主根,即 floor'ed 或 ceil'ed 值......如何最好地接近实际值? 最佳答
看起来这应该很容易,但我很困惑。我已经掌握了使用 dplyr 进行编程的大致技巧0.7,但为此苦苦挣扎:How do Iprogram in dplyr我想要编程的变量是否是一个字符串? 我正在抓取数
在 Rust 中取任意数的 n 次根的最佳方法是什么?例如,num crate 只允许取整数类型的第 n 个主根,即 floor'ed 或 ceil'ed 值......如何最好地接近实际值? 最佳答
我有一个 pandas 数据框,其中有一列名为“coverage”。对于一系列特定索引值,我想获取前 100 行的平均“覆盖率”值。例如,对于索引位置 1001,我想要第 901-1000 行的平均“
import pandas as pd data = {'date': ['1998-03-01', '2001-04-01','1998-06-01','2001-08-01','2001-05-0
我有一个包含 100 个数字的 NSArray。我想创建一个 5 个数字的 NSArray。第二个数组中的第一个数字是第一个数组中前 20 个数字的平均值。第二个数字是第一个数组中第二组 20 个数字
我该怎么做?我试过 abs() 但它只适用于整数。有内置的方法吗? CGFloat flo = -123; abs(flo) 返回 0 最佳答案 使用 fabs() CGFloat f = -123.
我正在采用以下计算的 log2: tl_out.a.bits.size := log2Ceil(s1_row * s2_column * 4.U) 其中,s1_row 和 s2_column 是 UI
如何从 m 个元素集合中取出 n 个元素,以便在元素用完时从头开始? List list = new List() {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; List newL
我已经完成了研究,但似乎找不到有关该主题的足够文档。 在 Object streams 上尝试一些代码时,我注意到将 BufferedOutputStream 放入 ObjectOutputStrea
我需要计算数据中连续时间组之间的差异,如下所示 from io import StringIO import pandas as pd strio = StringIO("""\
我在 Mongo 数据库中有以下文档: { _id: 1, question: "Blue or red?", __v: 0, votes: [9, 5] } 我想在后
好吧,宇宙中一定有人知道这个问题的答案。 我已经在这里问过这个问题,但仍然没有解决方案。 我需要保留和换行 div 中的文本。到目前为止,我很难想出解决方案。我找到的最佳解决方案并不适用于所有浏览器。
我正在尝试采用 3 个单独的整数输入(年、月、日)并采用这 3 个条目并从中形成一个日期对象,以便我可以使用它来比较其他日期。 这是我目前所拥有的,不知从何而来: public void compar
在我的 IOS 项目中,我有一个包含该函数的自定义 Logger 类(单例) - (void)log:(NSString *)domain logLevel:(int)level logMessage
我是一名优秀的程序员,十分优秀!