SSE:跨页边界的未对齐加载和存储

2024-05-20

我在页面边界旁边执行未对齐加载或存储之前读过某处(例如使用_mm_loadu_si128 / _mm_storeu_si128内在函数),代码应首先检查整个向量(在本例中为 16 个字节)是否属于同一页,如果不属于同一页,则切换到非向量指令。我知道如果下一页不属于进程,则需要这样做以防止核心转储。

但是,如果两个页面都属于进程(例如,它们是一个缓冲区的一部分,并且我知道该缓冲区的大小)怎么办?我编写了一个小型测试程序,该程序执行未对齐的加载并存储跨页边界的内容,并且它没有崩溃。在这种情况下,我是否必须始终检查页面边界,或者足以确保我不会溢出缓冲区?

环境:Linux、x86_64、gcc


页行分割对性能不利,但不会影响未对齐访问的正确性。确保您不会读取超出缓冲区末尾的内容就足够了,当你提前知道长度时。


为了正确性,在实现类似的东西时你经常需要担心它strlen,当您找到哨兵值时,循环将停止。该值可以位于向量内的任何位置,因此只需执行 16B 未对齐加载就会读取超出数组末尾的内容。如果终止0位于一页的最后一个字节,并且下一页不可读,并且当前位置指针未对齐,加载包括0byte 还将包含来自不可读页面的字节,因此会出错。

一种解决方案是执行标量直到指针对齐,然后加载对齐的向量。对齐的加载始终完全来自一页,也来自一个缓存行。因此,即使您将读取超出字符串末尾的一些字节,也保证不会出错。Valgrind http://valgrind.org/不过,标准库可能对此不满意strlen实现使用这个。

您可以从字符串的开头执行未对齐的向量(只要不会跨越页线),然后执行对齐的加载,而不是在对齐指针之前使用标量。第一个对齐的加载将与第一个未对齐的加载重叠,但这对于像 strlen 这样的函数来说完全没问题,因为它不关心是否两次看到相同的数据。


出于性能原因,避免页行分割可能是值得的。即使您知道 src 指针未对齐,让硬件处理缓存行拆分通常会更快。但在 Skylake 之前,页面分割有大约 100c 的额外延迟。 (Skylake 低至 5c https://stackoverflow.com/questions/37361145/deoptimizing-a-program-for-the-pipeline-in-intel-sandybridge-family-cpus/37362225#37362225)。如果您有多个可以相对彼此以不同方式对齐的指针,则不能总是仅使用序言来对齐 src。 (例如。c[i] = a[i] + b[i], and c已对齐,但是b isn't.)

在这种情况下,可能值得使用分支在页面拆分之前和之后进行对齐加载,并将它们与palignr.

分支错误预测(~15c)比页面分割延迟要便宜,但会延迟所有内容(不仅仅是加载)。所以也可能not是否值得,具体取决于硬件以及计算与内存访问的比率。


如果你正在编写一个函数usually使用对齐指针调用,仅使用未对齐的加载/存储指令是有意义的。任何检测未对齐的序言对于已经对齐的情况来说都只是额外的开销,并且在现代硬件(Nehalem 和更新的)上,地址上未对齐的加载在运行时被对齐,其性能与对齐的加载指令相同。 (但是您需要 AVX 将未对齐的加载折叠到其他指令中作为内存操作数。例如vpxor xmm0, xmm1, [rsi])

通过添加代码来处理未对齐的输入,您可以减慢常见对齐情况的速度,从而加快不常见未对齐情况的速度。对未对齐加载/存储的快速硬件支持使软件可以在少数情况下将其留给硬件。

(如果输入未对齐很常见,那么它is值得使用序言来对齐输入指针,尤其是。如果您使用 AVX。顺序 32B AVX 加载将缓存行分割所有其他加载。)

See Agner Fog 的优化装配指南 http://agner.org/optimize/欲了解更多信息,以及其他链接x86 /questions/tagged/x86标签维基。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SSE:跨页边界的未对齐加载和存储 的相关文章

随机推荐

  • UICollectionView 未出现

    我正在尝试设置UICollectionView 以编程方式在我的视图控制器中扩展UIViewController 由于某种原因 我的收藏视图根本没有显示 以下是我所拥有的 为什么没有出现 我将它连接到委托和数据源并将其添加为子视图self
  • 是否可以在单个 POM 中执行两个不同的 maven exec-maven-plugin

    我使用执行以下代码mvn exec java com mycompany FooServer 我想添加另一个我可以执行的服务器mvn exec java com mycompany BarServer 我如何在单个 pom 文件中做到这一点
  • Python 原生协程和 send()

    基于生成器的协程有一个send 方法 允许调用者和被调用者之间进行双向通信 并从调用者恢复生成的生成器协程 这是将生成器转变为协程的功能 虽然新本地人async await协程为异步 I O 提供了卓越的支持 我不知道如何获得相当于send
  • 配置 HttpClientFactory 以使用当前请求上下文中的数据

    随着新HttpClientFactory https www stevejgordon co uk introduction to httpclientfactory aspnetcore在 ASP NET Core 2 1 中 使用基本
  • 如何在 mongoid 中使用 or 条件进行查询

    如何在 Mongoid 中使用 or 条件进行查询 这是 OR 在 mongoid 中查询 如果你想要像下面这样的查询 select from user where id 10 or name hitesh 在带有 mongoid 的 Ra
  • Android ACTION_SEND 意图未填充主题或正文

    我的应用程序中有代码可以让用户向开发人员发送电子邮件 它应该预先填充 收件人 字段 主题 字段和 正文 字段 然而 当我运行时 它会填充 收件人 但会忽略其他额外内容 例如主题 正文和选择器文本 我在两台测试设备上看到了这种行为 一台运行
  • 编码:类型错误:write() 参数必须是 str,而不是 bytes

    我对 python 有初步的了解 但不清楚处理二进制编码问题 我正在尝试运行 firefox webextensions 示例中的示例代码 其中 python 脚本发送由 javascript 程序读取的文本 我不断遇到编码错误 蟒蛇代码是
  • 从返回堆栈返回后,片段不刷新内容

    我有一个ZooFragment其中包含一个ViewPager This ViewPager有三个孩子 LionFragment LeopardFragment and TigerFragment 每个子节点都可以请求事务来调用新的ZooFr
  • 在画布上绘制多个矩形

    我试图在鼠标移动时在画布上添加多个矩形 但是当我在图像上绘制矩形时 画布上的背面图像也会被清除 我不想删除它 我想要画布上有多个矩形而不清除画布图像 请检查下面的 JavaScript 代码 var canvas document getE
  • 我的客户端 socket.io 在哪里?

    我使用 Express 和 React Engine 创建了一个同构 React 应用程序 现在我正在尝试连接socket io 在快速设置中我有 var express require express var app express va
  • jQuery.post 改变 HTML 中的一些特殊字符

    TinyMCE 中的示例数据 和 以上HTML代码 p 10003 and 9786 9999 9986 p 之前 工作正常 在保存的文档中获得相同的字符 function save and submit var tinyGenData t
  • CSS:水平滚动时背景不存在

    好的 我的背景设置如下 HTML div div CONTENT HERE div div CSS container background url image gif content width 800px margin auto 因此
  • 如何检测字符串中的非 ASCII 字符?

    如果我有一个 PHP 字符串 如何以有效的方式确定它是否至少包含一个非 ASCII 字符 我所说的非 ASCII 字符是指不属于该表的任何字符 http www asciitable com http www asciitable com
  • Flask 环境变量被忽略(FLASK_ENV 和 FLASK_APP)WINDOWS 10

    After setting the environment variables FLASK ENV and FLASK APP running flask run will give me this error 该代码片段显示了命令提示符
  • Pytest报告摘要显示错误信息

    我对 pytest 挂钩和插件相对较新 我无法弄清楚如何让我的 pytest 代码为我提供测试执行摘要以及失败原因 考虑代码 class Foo def init self val self val val def test compare
  • 如何模拟MyBatis映射器接口?

    我正在为我的 Jersey Rest API 编写单元测试 该 API 在后台使用 MyBatis 这是我的课程结构 休息服务 Path api public class HelloRestService Inject HelloBean
  • 确定 NSView 是否绘制的正确方法

    有没有正确的方法来确定是否NSView实际上是否在当前视图层次结构中绘制 考虑以下情况 视图完全在屏幕外 不是强制性的 该视图不在视图层次结构的顶部 The isHidden and isHiddenOrHasHiddenAncestor不
  • CameraX Image拍照速度慢

    我正在使用 CameraX 这是我的图像捕获 mImageCapture ImageCapture Builder setCaptureMode ImageCapture CAPTURE MODE MINIMIZE LATENCY setT
  • MySQL NOT IN 来自同一个表中的另一列

    我想运行 mysql 查询来选择表中的所有行films其中的值title该列不存在于另一列的所有值中的任何位置 collection 这是我的表格的简化版本 其中包含内容 mysql gt select from films id titl
  • SSE:跨页边界的未对齐加载和存储

    我在页面边界旁边执行未对齐加载或存储之前读过某处 例如使用 mm loadu si128 mm storeu si128内在函数 代码应首先检查整个向量 在本例中为 16 个字节 是否属于同一页 如果不属于同一页 则切换到非向量指令 我知道