- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我试图在两种算法之间做出决定。一个将 8 个字节(两个对齐的 4 字节字)写入 2 个缓存线,另一个写入 3 个完整的缓存线。
如果 CPU 仅将更改后的 8 字节写回内存,则第一种算法使用的内存带宽要少得多:8 字节与 192 字节。如果 CPU 写入整个缓存行,那么 128 和 192 字节之间的差异就不那么明显了。
那么英特尔至强 CPU 如何写回内存呢?你会惊讶地发现,在谷歌中找到一个应该众所周知的东西的答案是多么困难。
据我了解,写入进入存储缓冲区,然后进入缓存。当脏缓存行从缓存中被逐出时,它们可能只会被写入内存,但英特尔是否会跟踪缓存行的哪些部分是脏的,或者只是转储整个内容?我相当怀疑他们跟踪缓存线粒度以下的东西。如果在缓存行被逐出之前有任何内容进入内存,我也会感到非常惊讶。
最佳答案
甚至对于 DRAM 本身,局部性也很重要,即使不考虑缓存也是如此。对脏缓存行进行 64B 连续字节的突发写入比向 16 个不同地址的 4B 写入 16 次要快得多。或者换句话说,写回整个缓存行并不比写回缓存行中的几个更改的字节慢多少。
What Every Programmer Should Know About Memory由 Ulrich Drepper 撰写,解释了很多有关在编程时避免内存瓶颈的内容。他包括了 DRAM 寻址的一些细节。 DRAM Controller 必须先选择一行,然后再选择一列。访问另一个虚拟内存页面也会导致 TLB 未命中。
DRAM 确实具有用于传输连续数据块的突发传输命令。 (显然是为了 CPU 写回缓存行而设计的)。现代计算机中的内存系统针对写入整个缓存行的使用模式进行了优化,因为这几乎总是发生。
缓存线是 CPU 跟踪脏与否的单位。可以使用比存在或不存在缓存线更小的线尺寸来跟踪脏度,但这需要额外的晶体管并且不值得。设置了多级缓存来传输整个缓存行,因此当需要读取整个缓存行时,它们可以尽可能快。
有所谓的非临时读/写 ( movnti/movntdqa
) 绕过缓存。这些用于在无论如何都会从缓存中逐出之前不会再次触及的数据(因此是非时间性的)。对于可以从缓存中受益的数据,它们是一个坏主意,但可以让您将 4 个字节写入内存,而不是整个缓存行。根据该内存范围的 MTRR,写入可能会或可能不会受到写入组合的影响。 (这与内存映射的 I/O 区域相关,其中两个相邻的 4B 写入与一个 8B 写入不同。)
只涉及两个缓存行的算法在这个分数上肯定有优势,除非需要更多的计算,或者特别是分支,才能确定要写入的内存。如果您需要帮助做决定,也许可以问一个不同的问题。 (请参阅 https://stackoverflow.com/tags/x86/info 上的链接,尤其是 Agner Fog 的指南,了解可帮助您自行决定的信息。)
请参阅 Cornstalks 的回答,了解有关在不同 CPU 上有多个线程接触同一内存的危险的警告。与单线程程序的额外写入相比,这可能会导致更大的减速。
关于caching - Intel Xeon CPU 如何写入内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31631073/
我有这个代码 var myChart = new FusionCharts("../themes/clean/charts/hbullet.swf", "myChartId", "400", "75
既然写入是立即进行的(复制到内核缓冲区并返回),那么使用 io_submit 进行写入有什么好处? 事实上,它 (aio/io_submit) 看起来更糟,因为您必须在堆上分配写入缓冲区并且不能使用基
我正在使用 mootool 的 Request.JSON 从 Twitter 检索推文。收到它后,我将写入目标 div 的 .innerHTML 属性。当我在本地将其作为文件进行测试时,即 file:
最终,我想将 Vertica DB 中的数据抓取到 Spark 中,训练机器学习模型,进行预测,并将这些预测存储到另一个 Vertica DB 中。 当前的问题是确定流程最后部分的瓶颈:将 Spark
我使用 WEKA 库编写了一个 Java 程序, 训练分类算法 使用经过训练的算法对未标记的数据集运行预测 将结果写入 .csv 文件 问题在于它当前写出离散分类结果(即算法猜测一行属于哪个类别)。我
背景 - 我正在考虑使用 clickonce 通过 clickonce(通过网站)部署 WinForms 应用程序。相对简单的应用程序的要素是: - 它是一个可执行文件和一个数据库文件(sqlite)
是否有更好的解决方案来快速初始化 C 数组(在堆上创建)?就像我们使用大括号一样 double** matrix_multiply(const double **l_matrix, const dou
我正在读取 JSON 文件,取出值并进行一些更改。 基本上我向数组添加了一些值。之后我想将其写回到文件中。当我将 JSONArray 写回文件时,会被写入字符串而不是 JSONArray 对象。怎样才
我为两个应用程序使用嵌入式数据库,其中一个是服务器,另一个是客户端。客户端应用程序。可以向服务器端发送获取数据请求以检索数据并显示在表格(或其他)中。问题是这样的:如何将获取的数据保存(写入)到页面文
是否有更好的解决方案来快速初始化 C 数组(在堆上创建)?就像我们使用大括号一样 double** matrix_multiply(const double **l_matrix, const dou
从问题得出问题:找到所有 result = new ArrayList(); for (int i = 2; i >(i%8) & 0x1) == 0) { result.add(i
由于某种原因,它没有写入 CSV。谁能明白为什么它不写吗? def main(): list_of_emails = read_email_csv() #read input file, cr
关闭。 这个问题是 not reproducible or was caused by typos 。它目前不接受答案。 这个问题是由于错别字或无法再重现的问题引起的。虽然类似的问题可能在这里出现,
我目前正在开发一个保存和加载程序,但我无法获得正确的结果。 编写程序: #include #include #define FILENAME "Save" #define COUNT 6 type
import java.io.*; public class Main2 { public static void main(String[] args) throws Exception {
我需要使用预定义位置字符串“Office”从所有日历中检索所有 iOS 事件,然后将结果写入 NSLog 和 UITextView。 到目前为止,这是我的代码: #import "ViewCo
我正在尝试将 BOOL 值写入 PFInstallation 中的列,但会不停地崩溃: - (IBAction)pushSwitch:(id)sender { NSUserDefaults *push
我以前在学校学过一些简单的数据库编程,但现在我正在尝试学习最佳实践,因为我正在编写更复杂的应用程序。写入 MySQL 数据库并不难,但我想知道让分布式应用程序写入 Amazon EC2 上的远程数据库
是否可以写回到ResourceBundle?目前我正在使用 ResourceBundle 来存储信息,在运行时使用以下内容读取信息 while(ResourceBundle.getBundle("bu
关闭。这个问题是not reproducible or was caused by typos .它目前不接受答案。 这个问题是由于错别字或无法再重现的问题引起的。虽然类似的问题可能是on-topi
我是一名优秀的程序员,十分优秀!