- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
首先让我以我知道这类微优化很少具有成本效益这一事实作为开头。我很好奇东西是如何工作的。对于所有高速缓存线编号等,我考虑的是 x86-64 i5 Intel CPU。对于不同的 CPU,这些数字显然会有所不同。
我经常认为向前移动数组比向后移动更快。我相信这是因为拉入大量数据是以面向前的方式完成的——也就是说,如果我读取字节 0x128,那么缓存线(假设长度为 64 字节)将以字节 0x128 读取—— 0x191 包括在内。因此,如果我要访问的下一个字节位于 0x129,那么它已经在缓存中。
但是,读了一点之后,我现在的印象是这实际上并不重要?因为缓存行对齐将在最近的 64 可分边界处选择起点,所以如果我选择字节 0x127 开始,我将加载 0x64-0x127 (含),因此缓存中的数据将用于我的向后走。当从 0x128 转换到 0x127 时,我会遇到缓存缺失,但这是我为这个示例选择地址的位置的结果,而不是任何现实世界的考虑。
我知道缓存线是作为 8 字节 block 读入的,因此如果我们向后走,则必须在第一个操作开始之前加载完整的缓存线,但我怀疑这会产生巨大的影响区别。
如果我就在这里,有人可以澄清一下吗?老我错了?我已经搜索了一整天,但仍然无法得到最终答案。
tl;dr:我们在数组中行走的方向真的那么重要吗?它真的有区别吗?过去有什么不同吗? (到 15 年前左右)
我用下面的基本代码测试过,前后看到的结果是一样的:
#include <windows.h>
#include <iostream>
// Size of dataset
#define SIZE_OF_ARRAY 1024*1024*256
// Are we walking forwards or backwards?
#define FORWARDS 1
int main()
{
// Timer setup
LARGE_INTEGER StartingTime, EndingTime, ElapsedMicroseconds;
LARGE_INTEGER Frequency;
int* intArray = new int[SIZE_OF_ARRAY];
// Memset - shouldn't affect the test because my cache isn't 256MB!
memset(intArray, 0, SIZE_OF_ARRAY);
// Arbitrary numbers for break points
intArray[SIZE_OF_ARRAY - 1] = 55;
intArray[0] = 15;
int* backwardsPtr = &intArray[SIZE_OF_ARRAY - 1];
QueryPerformanceFrequency(&Frequency);
QueryPerformanceCounter(&StartingTime);
// Actual code
if (FORWARDS)
{
while (true)
{
if (*(intArray++) == 55)
break;
}
}
else
{
while (true)
{
if (*(backwardsPtr--) == 15)
break;
}
}
// Cleanup
QueryPerformanceCounter(&EndingTime);
ElapsedMicroseconds.QuadPart = EndingTime.QuadPart - StartingTime.QuadPart;
ElapsedMicroseconds.QuadPart *= 1000000;
ElapsedMicroseconds.QuadPart /= Frequency.QuadPart;
std::cout << ElapsedMicroseconds.QuadPart << std::endl;
// So I can read the output
char a;
std::cin >> a;
return 0;
}
对于 A) Windows 代码和 B) Hacky 实现,我深表歉意。它被放在一起来检验一个假设,但不能证明推理。
任何有关步行方向如何产生影响的信息,不仅是缓存,还有其他方面,将不胜感激!
最佳答案
正如您的实验所表明的那样,没有区别。与处理器和 L1 高速缓存之间的接口(interface)不同,内存系统处理完整的高速缓存行,而不是字节。正如@user657267 指出的那样,存在特定于处理器的预取器。这些可能偏好向前而不是向后,但我对此深表怀疑。所有现代预取器都检测方向而不是假设它们。此外,它们还检测步幅。它们涉及极其复杂的逻辑,而且像方向这样简单的东西不会成为它们的失败。
简短的回答:朝任何一个你想要的方向前进,并享受相同的性能!
关于c++ - Forwards vs Backwards 数组行走,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25437612/
我是学习深度学习的新手,我一直在努力理解 Pytorch 中的“.backward()”是做什么的,因为它几乎完成了那里的大部分工作。因此,我试图详细了解反向函数的作用,因此,我将尝试逐步编写该函数的
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引起辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the he
我正在开发一个同时具有 GUI(图形)和 API(脚本)界面的应用程序。我们的产品有一个非常大的安装基础。许多客户投入了大量时间和精力来编写使用我们产品的脚本。 在我们所有的设计和实现中,我们(可以理
我从事的项目以源代码和二进制形式免费分发,因为我们的许多用户需要专门为他们的系统编译它。这需要一定程度的考虑,以保持与旧主机系统(主要是它们的编译器)的向后兼容性。 其中一些最糟糕的,例如 GCC 3
我需要在 Python 中创建一个树状结构。我有一个函数 get(parentId),它返回具有该父级的对象列表——我认为应该递归地完成。 结果应该是这样的:["root object", ["chi
我正在尝试为移动菜单制作动画,因此当点击它时三条纹应该变成“X”,当关闭菜单时它应该恢复为三条纹。 “X”的动画效果非常好,但关闭时它会跳回三条纹,而不是平滑地过渡回它。这是因为我当然完全删除了 x
训练用PyTorch编写的LSTM或RNN时,在loss.backward()上报错: RuntimeError: Trying to backward through the graph
为什么参数到atan2功能是“倒退”的?即,为什么它接受 y, x 形式的坐标而不是标准 x, y ? 最佳答案 因为它类似于atan(y / x) , 与 y作为分子和 x作为分母。 关于math
data.table很棒,因为我可以进行滚动连接,甚至可以在组内进行滚动连接! library(data.table) set.seed(42) metrics metrics[calendar,r
我正在开发一个 grails 插件,它添加了一个新的标签库并呈现了一个模板。 我的问题是这个模板输出一个 JSON 并且我不需要它被编码。 如果我使用 raw() 函数,它工作正常,但这与 grail
我想匹配字符串中的数字:'abc@2003,或其他@2017'我想通过 match 函数获得结果 [2003, 2007]。 let strReg = 'abc@2003, or something
Douglas Crockford,因此,JSLint 真的不喜欢 for 循环。大多数时候我同意,并使用 [].forEach 和 Object.keys(obj) 遍历数组或字典。 但是,在某些情
这个问题在这里已经有了答案: Difference between null == x and x == null? [duplicate] (5 个答案) 关闭 7 年前。 我正在查看一些代码,发
我有一个 PyTorch 计算图,它由一个执行某些计算的子图组成,这个计算的结果(我们称它为 x)然后被分支到另外两个子图中。这两个子图的每一个都会产生一些标量结果(我们称它们为 y1 和 y2)。我
不是从前面读取文件,而是可以向后读取它吗?这样输出是从文件的后面到文件的前面。 编辑:最后一行首先显示,而不是完全向后显示。 最佳答案 这是可能的,但很麻烦。 Lua API 提供 seek函数来设置
我用 Storyboard 创建了我的应用程序,直到很晚才意识到 iOS4.3 设备将不受支持。是否有一个选项可以将 Storyboard View 复制到 xib 中或在运行时以编程方式执行此操作?
我为那些犯了同样错误的人发布了这个问题。尝试计算梯度时出现此错误: criterion = torch.nn.CrossEntropyLoss() loss = criterion(y_hat, y_
我一直在阅读this article并且在他们的一节中指出: Lenses compose backwards. Can't we make (.) behave like functions? Yo
编辑:这对我来说是“倒退” - 我可能缺少一些直觉 给定一个 glm 变换函数,例如 glm::translate,两个参数首先是一个矩阵 m,然后是一个用于平移的 vector v。 直观上,我希望
我正在使用调查图/图遍历 compile group: 'org.jgrapht', name: 'jgrapht-core', version: '1.1.0' 使用下面的代码我可以创建一个简单的图
我是一名优秀的程序员,十分优秀!