- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
将范围与内存段相关联似乎并不困难。然后有一个汇编指令,它将 2 个整数视为“位置”和“偏移量”(如果设置,则另一个为“数据”),并返回数据和错误代码。这意味着在使用阵列时不再需要在速度和安全性/安全性之间做出选择。
另一个示例可能是验证源自特定内存范围的指令不能物理访问该范围之外的内存的函数。如果连接到主板的所有硬件都具有此功能(并且相互兼容),那么制作以与物理机几乎相同速度运行的完美虚拟机将是微不足道的。
达斯汀·苏达克
最佳答案
是的。
几十年前,Lisp machines执行同时验证检查(例如类型检查和边界检查),因为程序运行时假设程序和状态是有效的,如果检查失败则“回到过去”——不幸的是,这种获得“免费”运行时验证的能力在以下情况下丢失了传统(即 x86)机器成为主导。
https://en.wikipedia.org/wiki/Lisp_machine
Lisp Machines ran the tests in parallel with the more conventional single instruction additions. If the simultaneous tests failed, then the result was discarded and recomputed; this meant in many cases a speed increase by several factors. This simultaneous checking approach was used as well in testing the bounds of arrays when referenced, and other memory management necessities (not merely garbage collection or arrays).
BOUND
从技术上讲,x86 确实有硬件边界检查:
the BOUND
instruction于 1982 年在
Intel 80188 中推出(以及 Intel 286 及更高版本,但不包括 Intel 8086、8088 或 80186 处理器)。
BOUND
指令确实提供了硬件边界检查,我知道它间接导致了性能问题,因为它破坏了硬件分支预测器(
according to a Reddit thread ,但我不确定为什么),但也因为它需要在内存中的元组中指定边界- 这对性能来说很糟糕 - 我知道在运行时它并不比手动执行“如果
index
不在范围内
[x,y]
然后向程序或操作系统发出
BR
异常信号”的指令更快(所以你可能会想象添加
BOUND
指令是为了方便那些手工编写汇编代码的人,这在 1980 年代非常普遍)。
BOUND
指令仍然存在于今天的处理器中,但它没有包含在 AMD64 (x64) 中 - 可能是出于我上面解释的性能原因,也因为可能很少有人使用它(编译器可以轻松地用手动边界检查替换它) ,无论如何这可能具有更好的性能,因为它可以使用寄存器)。
BOUNDS
检查的约束)可能会覆盖先前为另一个指针编写的边界并以这种方式绕过检查 - 这主要是故意的代码问题尝试禁用安全功能(即恶意软件),但如果边界存储在堆栈中 - 并且考虑到破坏堆栈是多么容易,它的实用性就更少了。
BOUND
因为它提供了专用寄存器来存储边界范围,因此与
BOUND
相比,边界检查应该几乎为零成本。这需要内存访问。在 Intel 486 上
BOUND
说明
takes 7 cycles (与
CMP
相比,即使操作数是内存地址,它也需要
only 2 cycles)。在 Skylake 中,MPX 等价物(
BNDMK
、
BNDCL
和
BNDCU
)都是 1 周期指令和
BNDMK
可以摊销,因为它只需要为每个新指针调用一次)。
Our main conclusion is that Intel MPX is a promising technique that is not yet practical for widespread adoption. Intel MPX’s performance overheads are still high (~50% on average), and the supporting infrastructure has bugs which may cause compilation or runtime errors. Moreover, we showcase the design limitations of Intel MPX: it cannot detect temporal errors, may have false positives and false negatives in multithreaded code, and its restrictionson memory layout require substantial code changes for some programs.
char arr[10];
arr[9] = 'a';
arr[8] = 'b';
然后在 MPX 下执行:
Time Instruction Notes
1 BNDMK arr, arr+9 Set bounds 0 to 9.
2 BNDCL arr Check `arr` meets lower-bound.
3 BNDCU arr Check `arr` meets upper-bound.
4 MOV 'a' arr+9 Assign 'a' to arr+9.
5 MOV 'a' arr+8 Assign 'a' to arr+8.
但是在 Lisp 机器上(如果可以神奇地将 C 编译为 Lisp...),那么计算机中的程序-阅读器-硬件就有能力在执行“实际”指令的同时执行额外的“辅助”指令,从而允许“边”指令指示计算机在出现错误时忽略“实际”指令的结果:
Time Actual instruction Side instruction
1 MOV 'A' arr+9 ENSURE arr+9 BETWEEN arr, arr+9
2 MOV 'A' arr+8 ENSURE arr+8 BETWEEN arr, arr+9
我了解“侧面”指令的每周期指令与“实际”指令不同 - 因此对
Time=1
处的指令进行侧面检查可能只有在“实际”说明已经进展到
Time=3
后才能完成。 - 但如果检查失败,那么它会将失败指令的指令指针传递给异常处理程序,该异常处理程序将指示程序忽略在
Time=1
之后执行的指令的结果。 .我不知道他们如何在没有大量内存或一些强制执行暂停的情况下实现这一目标,也可能是内存围栏 -
constexpr
编译器可以证明的索引值永远不会越界,因此将完全省略 MPX 检查 - 所以假装它们是用户提供的变量 :) )。
struct BoundedPointer<T> { T* ptr, T* min, T* max }
- 这在技术上已经发生在 MPX 和其他基于软件的边界检查中,因为每个 protected 指针在
BNDMK
被调用时都定义了其边界)然后MMU 可以免费提供保护——但现在每个指针将消耗 24 个字节的内存,而不是当前的 8 个字节——或者与 32 位 x86 下的 4 个字节相比——RAM 充足,但仍然是有限的不应该浪费的资源。
/d2MPX
开关(
https://blogs.msdn.microsoft.com/vcblog/2016/01/20/visual-studio-2015-update-1-new-experimental-feature-mpx/ )。 Visual Studio 2017 中仍然提供支持,但微软尚未宣布它是否被视为主流(即非实验性)功能。
关于memory - 是否有任何 CPU 具有边界检查的硬件支持?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40752436/
这是代码片段。 请说出这种用小内存存储大数据的算法是什么。 public static void main(String[] args) { long longValue = 21474836
所以我使用 imap 从 gmail 和 outlook 接收电子邮件。 Gmail 像这样编码 =?UTF-8?B?UmU6IM69zq3OvyDOtc68zrHOuc67IG5ldyBlbWFpb
很久以前就学会了 C 代码;想用 Scheme 尝试一些新的和不同的东西。我正在尝试制作一个接受两个参数并返回两者中较大者的过程,例如 (define (larger x y) (if (> x
Azure 恢复服务保管库有两个备份配置选项 - LRS 与 GRS 这是一个有关 Azure 恢复服务保管库的问题。 当其驻留区域发生故障时,如何处理启用异地冗余的恢复服务保管库?如果未为恢复服务启
说,我有以下实体: @Entity public class A { @Id @GeneratedValue private Long id; @Embedded private
我有下一个问题。 我有下一个标准: criteria.add(Restrictions.in("entity.otherEntity", getOtherEntitiesList())); 如果我的
如果这是任何类型的重复,我会提前申请,但我找不到任何可以解决我的具体问题的内容。 这是我的程序: import java.util.Random; public class CarnivalGame{
我目前正在使用golang创建一个聚合管道,在其中使用“$ or”运算符查询文档。 结果是一堆需要分组的未分组文档,这样我就可以进入下一阶段,找到两个数据集之间的交集。 然后将其用于在单独的集合中进行
是否可以在正则表达式中创建 OR 条件。 我正在尝试查找包含此类模式的文件名列表的匹配项 第一个案例 xxxxx-hello.file 或者案例二 xxxx-hello-unasigned.file
该程序只是在用户输入行数时创建菱形的形状,因此它有 6 个 for 循环; 3 个循环创建第一个三角形,3 个循环创建另一个三角形,通过这 2 个三角形和 6 个循环,我们得到了一个菱形,这是整个程序
我有一个像这样的查询字符串 www.google.com?Department=Education & Finance&Department=Health 我有这些 li 标签,它们的查询字符串是这样
我有一个带有静态构造函数的类,我用它来读取 app.config 值。如何使用不同的配置值对类进行单元测试。我正在考虑在不同的应用程序域中运行每个测试,这样我就可以为每个测试执行静态构造函数 - 但我
我正在寻找一个可以容纳多个键的容器,如果我为其中一个键值输入保留值(例如 0),它会被视为“或”搜索。 map, int > myContainer; myContainer.insert(make_
我正在为 Web 应用程序创建数据库,并正在寻找一些建议来对可能具有多种类型的单个实体进行建模,每种类型具有不同的属性。 作为示例,假设我想为“数据源”对象创建一个关系模型。所有数据源都会有一些共享属
(1) =>CREATE TABLE T1(id BIGSERIAL PRIMARY KEY, name TEXT); CREATE TABLE (2) =>INSERT INTO T1 (name)
我不确定在使用别名时如何解决不明确的列引用。 假设有两个表,a 和 b,它们都有一个 name 列。如果我加入这两个表并为结果添加别名,我不知道如何为这两个表引用 name 列。我已经尝试了一些变体,
我的查询是: select * from table where id IN (1,5,4,3,2) 我想要的与这个顺序完全相同,不是从1...5,而是从1,5,4,3,2。我怎样才能做到这一点? 最
我正在使用 C# 代码执行动态生成的 MySQL 查询。抛出异常: CREATE TABLE dump ("@employee_OID" VARCHAR(50)); "{"You have an er
我有日期 2016-03-30T23:59:59.000000+0000。我可以知道它的格式是什么吗?因为如果我使用 yyyy-MM-dd'T'HH:mm:ss.SSS,它会抛出异常 最佳答案 Sim
我有一个示例模式,它的 SQL Fiddle 如下: http://sqlfiddle.com/#!2/6816b/2 这个 fiddle 只是根据 where 子句中的条件查询示例数据库,如下所示:
我是一名优秀的程序员,十分优秀!