- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我已经尝试了所有可能得出的推理,但我并不真正理解这个情节。
它基本上显示了从不同大小的数组以不同的步幅读取和写入的性能。
我知道对于像 4 个字节这样的小步幅,我读取了缓存中的所有单元格,因此我有很好的性能。但是当我拥有 2 MB 阵列和 4k 步幅时会发生什么?还是 4M 和 4k 步幅?为什么表现这么差?最后为什么当我有 1MB 数组并且步幅是大小的 1/8 时性能不错,当 1/4 大小性能变得最差,然后在一半大小时,性能 super 好?
请帮助我,这件事让我发疯。
在此链接,代码:https://dl.dropboxusercontent.com/u/18373264/membench/membench.c
最佳答案
您的代码在给定的时间间隔内循环而不是恒定的访问次数,您没有比较相同的工作量,并且并非所有缓存大小/步幅都享有相同的重复次数(因此它们获得不同的缓存机会)。
另请注意,第二个循环可能会被优化掉(内部 for
),因为您不使用 temp
任何地方。
编辑:
这里的另一个影响是 TLB 利用率:
在 4k 页面系统上,随着您在 4k 步长时增加步幅,您会享受到每个页面的利用率越来越低(最终在 4k 步幅上每页访问一次),这意味着访问时间会随着您的增长而增加必须在每次访问时访问第二级 TLB(甚至可能序列化您的访问,至少部分)。
由于您通过步幅大小对迭代计数进行了标准化,因此您通常会得到 (size / stride)
在最内层循环中访问,但是 * stride
外部。但是,您访问的唯一页面的数量不同 - 对于 2M 阵列、2k 步长,您将在内循环中进行 1024 次访问,但只有 512 个唯一页面,因此对 TLB L2 的访问次数为 512*2k。在 4k 步长上,仍然会有 512 个唯一页面,但是 512*4k TLB L2 访问。
对于 1M 阵列情况,您总共将有 256 个唯一页面,因此 2k 步长将具有 256 * 2k TLB L2 访问,而 4k 将再次具有两次。
这解释了为什么当您接近 4k 时每条线上的性能逐渐下降,以及为什么数组大小每增加一倍,相同步幅的时间就会增加一倍。较低的阵列大小可能仍然部分享受 L1 TLB,因此您看不到相同的效果(尽管我不确定为什么 512k 存在)。
现在,一旦您开始将步幅提高到 4k 以上,您会突然再次受益,因为您实际上是在跳过整个页面。 8K 步幅将仅访问每隔一个页面,对于相同的数组大小,将总 TLB 访问的一半作为 4k,以此类推。
关于performance - 内存基准图 : understanding cache behaviour,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20434193/
这个问题在这里已经有了答案: What is the rationale behind decltype behavior? (3 个答案) 关闭 5 年前。 int i = 12; decltyp
这个问题在这里已经有了答案: Undefined, unspecified and implementation-defined behavior (9 个回答) 关闭 4 年前。 C 标准 (AF
我提到了 This Question但没有答案对我有用。所以基本上我有一个 BottomNavigationView,它在向下滚动时隐藏并在向上滚动时显示。当我通过触摸滚动 Recycler View
我正在寻找一种利用mDNS,floodsub和kademlia DHT的网络行为。到目前为止,我已经使所有这些服务都可以使用,但是还不能将这些服务的响应用于有意义的事情。 理想情况下,我将能够将来自行
此代码适用于我的网站: $(function(){ $('.link-follow-stop').on('click', function(event){ console.lo
private synchronized Map calculateStanding() { System.out.println("Calculate standing for
我最近正在测试 的点击事件(点击后找到一个文本框)并发现了一些不寻常的东西。 在 HTML 标记中, 如果在里面, 上面的点击事件标签触发了两次 如果在之外,点击事件为按预期运行 为了更好地理解我要
我尝试了以下两种情况: void ssss(int b){ System.out.println ("int"+b); } void ssss(double b){ System.out.
由于截止日期的压力,我可能会忽略一些东西。但是这种行为令我惊讶。 好像游标缓存了100行,而continue语句刷新了缓存 并从获取新缓存的第一条记录开始。 我将其范围缩小到以下脚本: drop ta
我是德尔福的新手。在 TStrem 类的文档中,我读到它是一个抽象类。所以我认为当我尝试使用 创建它时编译器会出错 stream := TStream.Create(); 为什么不呢? 最佳答案 De
在 Bjarne Stroustrup 的“C++ 之旅”(第二版)的第 18 页上,他指出“对于几乎所有类型,读取或写入未初始化变量的效果是未定义的”。 我明白为什么读取未初始化的变量是未定义的行为
我正在尝试使用两个线程的代码,一个线程递增共享长变量,另一个线程递减 var。 class Shared { private long a; public void incr() {
我们都听过这样的警告:如果您在 C 或 C++ 中调用未定义的行为,任何事情都可能发生。 这是否仅限于任何运行时行为,还是还包括任何编译时行为?特别是,编译器在遇到调用未定义行为的构造时是否允许拒绝代
我在 C++ 中编写了一个简单的函数来计算具有长度、宽度和高度的 Box 对象的体积。这是一个类的一部分,所以 l,b,h是私有(private)成员: long long CalculateVolu
我对以下声明有一些疑问: SELECT 1 FROM dual WHERE DECODE(1, 0, (SELECT COUNT(*) from tbl
我正在做一项作业,要求我编写一些 unix 的 ls 代码。我遇到问题的部分是 -R 选项。 一些背景:我使用的结构包含 2 个列表,一个用于文件,另一个用于运行 ls 时作为参数传递的目录。如果除了
我正在开发一个使用 Spring 数据 的 Java Spring 项目。 它使用 repositories 在狗被主人收集时从 Kennel Object 中移除 Dog Objects。 请注意,
我有一个 NSMutableArray,我分配给它: NSMutableArray *newElements = [[NSMutableArray alloc] initWithObjects:sel
我很少使用 Python,所以我不清楚为什么允许这样的行为:没有 w 对象,因此它没有 s 属性,那为什么 f 允许进行 w.s 赋值? >>> def f(): w.s="ads" #al
我有一个网站,其中一些元素具有 position: fixed。它在桌面浏览器上看起来不错,但在我的手机(Xperia Arc,Android 2.3)上,这些元素会随着页面滚动,直到您从屏幕上松开手
我是一名优秀的程序员,十分优秀!