问题标签 [micro-architecture]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
3646 浏览

x86 - 返回堆栈缓冲区?

据我了解,返回堆栈缓冲区仅支持 4 到 16 个条目(来自 wiki:http ://en.wikipedia.org/wiki/Branch_predictor#Prediction_of_function_returns )并且不是键值对(基于 ret 指令的位置索引)。这是真的吗?当上下文切换发生时 RSB 会发生什么?

假设我们在返回堆栈缓冲区长度为 16 的 CPU 中处理了 50 个未返回的函数,之后会发生什么?这是否意味着所有预测都失败了?你能举例说明吗?这种情况在递归函数调用中是否相同?

0 投票
3 回答
736 浏览

algorithm - 现代 X86 处理器如何实际计算乘法?

我正在看一些关于算法的讲座,教授用乘法作为如何改进朴素算法的例子......

它让我意识到乘法并不是那么明显,虽然当我编码时我只是认为它是一个简单的原子操作,乘法需要一个算法来运行,它不像求和数字那样工作。

所以我想知道,现代桌面处理器实际使用什么算法?我猜他们不依赖对数表,也不用数千和循环......

0 投票
3 回答
1368 浏览

c - 内存依赖推测是否会阻止 BN_consttime_swap 成为常量时间?

语境

OpenSSL 中的功能 BN_consttime_swap很漂亮。在此代码段中,condition已计算为0or (BN_ULONG)-1

目的是为了确保更高级别的 bignum 操作花费恒定的时间,这个函数要么交换两个 bignum,要么在恒定的时间内将它们留在原处。当它把它们留在原地时,它实际上读取每个 bignum 的每个单词,计算一个与旧单词相同的新单词,并将结果写回原始位置。

目的是这将花费与 bignums 被有效交换的时间相同的时间。

在这个问题中,我假设一个现代的、广泛使用的架构,例如 Agner Fog 在他的优化手册中描述的架构。还假定将 C 代码直接转换为汇编(没有 C 编译器取消程序员的努力)。

问题

我试图理解上面的构造是否被描述为“尽力而为”的恒定时间执行,还是完美的恒定时间执行。

特别是,我担心调用a函数时 bignum 已经在 L1 数据缓存中BN_consttime_swap,而函数返回后的代码立即开始处理 bignum的情况a。在现代处理器上,可以同时运行足够多的指令,以便在使用 bignum 时复制不会在技术上完成a。允许调用后的指令BN_consttime_swap工作的机制a内存依赖推测。为了论证,让我们假设幼稚的内存依赖推测。

这个问题似乎归结为:

当处理器最终检测到BN_consttime_swap从内存中读取的代码(与推测相反,已写入函数内部)时,它是在检测到地址已被写入后立即取消推测执行,还是允许自己当它检测到已写入的值与已经存在的值相同时保留它?

在第一种情况下,BN_consttime_swap看起来它实现了完美的恒定时间。在第二种情况下,它只是尽力而为的常数时间:如果没有交换 bignums,则调用之后的代码的执行BN_consttime_swap速度将比交换它们时快得多。

即使在第二种情况下,这看起来也可以在可预见的未来(只要处理器保持足够幼稚)通过为两个 bignums 中的每一个的每个单词写入一个与两个可能的 final 不同的值来修复值之前再次写入旧值或新值。在某些时候可能需要使用volatile类型限定符以防止普通编译器过度优化序列,但听起来仍然可行。

注意:我知道商店转发,但商店转发只是一个捷径。它不会阻止在它应该之后的写入之前执行读取。在某些情况下它会失败,尽管在这种情况下人们不会期望它会失败。

0 投票
1 回答
320 浏览

c - 指令缓存加载和逐出规则

我试图了解指令缓存是如何工作的。

  • 执行代码块时预取了多少额外的缓存线?它是否考虑到分支预测?

  • 如果一个代码块包含一个函数调用,函数代码体是按顺序加载还是在缓存的不同部分加载?

例如,以下代码片段是否相同?

如果条件很少为真,哪一个会减少指令序列中的“漏洞”?

  • 如果我的第一个示例是经常运行的代码的一部分并且if条件永远不会为真,那么if条件的主体最终会被驱逐,而代码主体的其余部分保持原样吗?

我假设这些问题没有取决于特定微架构的答案。但万一他们这样做了,我有一个 x86-64 Intel Sandy Bridge。

0 投票
0 回答
2533 浏览

caching - 为什么(NVIDIA)GPU L1 缓存线比 L2 缓存线长?

在 NVIDIA Fermi 和 Kepler GPU(也可能是 Maxwell)中,L1 缓存线的长度为 128 字节,而 L2 缓存线的长度为 32 字节。不应该反过来吗?我的意思是,L1 要小得多,它不应该尝试缓存较短的内存段以防止抖动吗?

0 投票
0 回答
128 浏览

x86 - 使用 MOVDQU 实现的复制循环显示了较大的运行间差异

我正在寻求解释我在循环中看到的结果,该循环使用 x86 movdqu 指令从某个源内存位置移动 64 字节到某个目标内存位置(movdqu 指令支持将 16 字节数据从/移到 xmm-寄存器到/从未对齐的内存位置)。这是实现类似于 memcpy()/java.lang.System.arraycopy() 的函数的代码的一部分

我尝试使用两种不同的模式来实现副本:

模式1

在此模式中,rsi 保存源(src)地址,rdi 保存目标(dst)地址,xmm 寄存器用作临时寄存器。此代码的迭代次数与 copylen_in_bytes/64 一样多。如您所见,这里遵循 ld-ld-st-st-ld-ld-st-st 加载存储模式。

模式2

在模式 2 中,遵循 ld-st-ld-st-ld-st-ld-st 模式。

观察

在运行此代码几百次时,其中 src 和 dst 在不同的 8 字节边界处对齐,我观察到以下内容:

在 Westmere (至强 X5690)

Pattern1 表现出非常高的运行间差异。

Pattern2 几乎没有变化。

Pattern2 上的最小时间(最快观察时间)比 Pattern1 上的最小时间高(约 8%)。

在 Ivybridge (Xean E5-2697 v2)

Pattern1 表现出非常高的运行间差异。

Pattern2 几乎没有变化。

Pattern2 的最小时间比 Pattern1 的最小时间高(~20%)。

哈斯韦尔(酷睿 i7-4770)

Pattern1 没有表现出非常高的运行间差异。

Pattern2 几乎没有变化。

Pattern2 的最小时间比 Pattern1 的最小时间高(~20%)。

奇怪的是,在 Westmere 和 Ivybridge 上,src/dest 的对齐与不良结果(导致高方差)之间似乎没有相关性。我看到相同 src/dest 对齐的好坏数字。

问题

我知道跨越缓存行的 movdqu 会比不跨越缓存行的 movdqu 执行得更差,但我不明白以下内容:

1) 为什么 Pattern1 在 Westmere 和 Ivybridge 上表现出高方差?加载存储的顺序有何不同?

2) 为什么 Pattern2 上的最小时间比 Pattern1 慢,跨不同的架构?

感谢您花时间阅读这篇长文。

卡尔提克

0 投票
2 回答
213 浏览

intel - hlt 期间程序计数器的状态

在 Intel 8085 微处理器中,程序计数器准确地在什么点(t 状态)更新?是在 t1 之后(即,就在 PC 中的当前地址被放置在地址总线上时)还是在 t3,当指令提取完成时?

另外,当遇到 hlt 指令时,程序计数器的状态会发生什么变化?它是递增还是包含当前 hlt 指令的地址?

0 投票
1 回答
82 浏览

cpu - 缓存线如何注册数据传输?

假设我有一个int包含 10 个元素的数组。使用 64 字节的缓存线,它可以容纳 16 个数组元素,从arr[0]arr[15]

例如,我想知道当您arr[5]从 L1 高速缓存中读取到寄存器时会发生什么。这个操作是如何进行的?cpu 可以选择一个缓存线的偏移量并读取下一个n字节吗?

0 投票
1 回答
1917 浏览

node.js - 将图像上传请求转发到另一台服务器

我正在尝试基于所谓的“微架构”(基本上是多个可以完全独立运行但同时协同工作的较小 NodeJS 项目)构建一个 NodeJS REST API 项目。

目前,用户可以从应用程序上传图像,然后我的 NodeJS 后端会适当地处理和保存它们。

现在,我想做的是以下内容:

用户从应用程序中选择要上传的图像 -> 应用程序向“主 API”端点发出请求 -> 主 API 端点然后将此请求转发给“图像服务” -> 一旦图像服务(这是一个完全不同的服务器)已成功完成,它应该将存储图像的 URL 返回到主 API 服务器端点,然后将信息返回给应用程序。

我的问题是,如何将图像上传请求从一台服务器转发到另一台服务器?理想情况下,我不希望 Main API 临时存储图像,然后向图像服务发出请求。

我想要的是尝试将 Main API 接收到的数据直接转发到图像服务服务器。我想你可以说我想将数据从一个地方“流式传输”到另一个地方,而不必临时存储在磁盘或内存上。我实际上只是希望它从一台服务器“隧道”到另一台服务器。

这可能吗?这是一种有效的方法吗?我只想让应用程序访问 1 个中心点,我不想让它知道这个图像服务服务器。我希望该应用程序只向主 API 发出请求,然后它会根据需要调用我的其他小服务。

我正在使用 NodeJS、Express、Multer(用于图像上传)和 Digital Ocean 托管(如果这有什么不同的话)。

0 投票
1 回答
2002 浏览

c++ - wait() 函数有什么作用?

嗨,我开始学习 Java,目前正在尝试学习 C++。我有这段代码,无法锻炼它的作用。我假设它使程序在启动之前等待一段时间。但是一些进一步的解释将非常有用。

我已经对我想要进一步解释的部分添加了评论。