有没有办法将寄存器文件视为 ARMv8 中的数组(标量或 Neon)?

2023-12-08

假设我有一个短数组v说 8int64_t。我有一个算法需要访问该数组的不同元素,这些元素不是编译时常量,例如就像是v[(i + j)/2] += ...其中i and j是不受任何类型的常量传播影响的变量。

通常,我会保留内存中的数组,计算数组索引,从内存中的该位置加载数组,然后存储结果。

但是假设,出于我不会讨论的正当理由,我想将完整数组保留在寄存器中——该数组的大小是有限的并且适合寄存器组。

如果我只是从数组中读取而不是写入数组,我可以使用(在 ARMv8 NEON 中)TBL 指令来执行表查找。但写作的情况又如何呢?

我能想到的就是自修改代码,将数组索引直接编码到指令中并执行它。我知道这在第一次运行时会带来性能损失,但如果一遍又一遍地执行相同的代码,它甚至可能会起作用。

除此之外,还有什么想法吗?有可能吗?我回顾了 ARMv8 架构参考手册中与指令集和编码相关的部分,到目前为止我倾向于说“不”,但也许有人知道一个晦涩的指令或寻址模式在这里会有所帮助。


如果您想访问x8,那么除了有一条编码指令之外别无他法x8作为源寄存器。因此,除了在运行时发出指令之外,我能想到的唯一基于索引的解决方案是为每个寄存器设置一个存根,并像 switch-case 一样基于索引进行分支。假设您的数组跨度为 x8 到 x15:

.p2align 2 // maybe change this to align to cacheline size?
read_reg:
    adr x2, 1f
    add x2, x0, lsl 3
    br x2
1:
    mov x0, x8
    ret
    mov x0, x9
    ret
    mov x0, x10
    ret
    mov x0, x11
    ret
    mov x0, x12
    ret
    mov x0, x13
    ret
    mov x0, x14
    ret
    mov x0, x15
    ret

写作也会以同样的方式进行。这当然有可能搞乱分支预测。我能想到的另一种完全不使用分支的“黑客”是结合csel直接移动到nzcv系统寄存器:

.p2align 2
read_reg:
    lsl x0, x0, 28
    msr nzcv, x0
    csel x4, x8, x9, vc // bit 0
    csel x5, x10, x11, vc
    csel x6, x12, x13, vc
    csel x7, x14, x15, vc
    csel x4, x4, x5, lo // bit 1
    csel x5, x6, x7, lo
    csel x0, x4, x5, ne // bit 2
    ret

这可以扩展到最多 16 个寄存器。我不太确定性能限制msr或者是否需要isb但在某些架构上 - 至少在 Apple M1 上,情况并非如此。而且写入的情况不会那么紧凑,因为您至少需要 8 条指令来定位每个寄存器。 :/

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

有没有办法将寄存器文件视为 ARMv8 中的数组(标量或 Neon)? 的相关文章

  • 什么时候汇编比C更快? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 Locked 这个问题及其答案是locked help locked posts因为这个问题是题外话 但却具有历史意义 目前不接受新的
  • 汇编-符号标志和奇偶校验标志

    我不明白什么时候设置标志标志 什么时候设置奇偶校验 据我所知 符号标志表示运算结果的符号 0表示正数 1表示负数 那么为什么在下一个代码中 mov al 5 sub al 124 SF为零 结果是负数 关于PF 为什么a和b中设置了PF a
  • CALL指令是否总是将EIP指向的地址压入堆栈?

    x86架构中函数调用时是否存在返回地址不入栈的情况 No CALL根据定义 将在跳转到目标地址之前将返回地址压入堆栈 该返回地址是EIP or RIP sizeof call instruction 通常为 5 个字节 英特尔 64 和 I
  • Visual Studio 2017 上的简单装配程序

    386 model flat c stack 100h printf PROTO arg1 Ptr Byte data msg1 byte Hello World 0Ah 0 code main proc INVOKE printf ADD
  • 汇编基础知识:输出寄存器值

    我刚刚开始学习汇编语言 我已经陷入了 在屏幕上显示存储在寄存器中的十进制值 的部分 我使用 emu8086 任何帮助将不胜感激 model small Specifies the memory model used for program
  • 近调用/跳转表并不总是在引导加载程序中工作

    一般问题 我一直在开发一个简单的引导加载程序 并在某些环境中偶然发现了一个问题 在这些环境中 此类指令不起作用 mov si call tbl SI Call table pointer call call tbl Call print c
  • 两个基本的 ANTLR 问题

    我正在尝试使用 ANTLR 来获取简单的语法并生成汇编输出 我在 ANTLR 中选择的语言是 Python 许多教程看起来非常复杂或详细阐述与我无关的事情 我真的只需要一些非常简单的功能 所以我有两个问题 将值从一个规则 返回 到另一规则
  • Nasm 打印到下一行

    我用 nasm Assembly 编写了以下程序 section text global start start Input variables mov edx inLen mov ecx inMsg mov ebx 1 mov eax 4
  • 为什么在强度降低乘法和循环进位加法之后,这段代码的执行速度会变慢?

    我正在读书阿格纳 雾 https en wikipedia org wiki Agner Fog s 优化手册 https en wikipedia org wiki Agner Fog Optimization 我遇到了这个例子 doub
  • 寄存器寻址模式与直接寻址模式

    我在试卷中遇到过这个问题 它指出 哪种给定的寻址模式更快 为什么 寄存器寻址方式 直接寻址方式 现在根据我的说法 寄存器寻址模式应该更快 因为寄存器是计算机中最快的存储位置 这是正确答案吗 请帮忙 谢谢 两种寻址模式之间的区别是 地址的来源
  • 弹出 x86 堆栈以访问函数 arg 时出现分段错误

    我正在尝试链接 x86 程序集和 C 我的C程序 extern int plus 10 int include
  • 程序集比较标志理解

    我正在努力理解汇编程序中的以下代码片段 if EAX gt 5 EBX 1 else EBX 2 在汇编程序中 可以写如下 根据我的书 模拟jge操作说明 https www felixcloutier com x86 jcc您通常会使用
  • 如何在程序中将自己缝合到自己的尾部,无限循环地封装 64KB 代码段?

    如果指令的顺序执行经过偏移量 65535 则8086将从同一代码段中的偏移量 0 处获取下一个指令字节 接下来的 COM 程序利用这一事实 不断将其整个代码 总共 32 个字节 缝合到自己的尾部 环绕在 64KB 代码段中 你可以称之为二元
  • 是否可以在VM内使用VMX CPU指令?

    VM guest 内部的进程是否有可能使用 VMX AMD V VT x CPU 指令 然后由外部 VMM 处理而不是直接在 CPU 上处理 Edit 假设外部VM使用VMX本身来管理其虚拟客户机 即它在Ring 1中运行 如果可能的话 是
  • 在 x86 汇编中将 64 位常量移至内存

    我正在使用 Intel x64 程序集 NASM 编译器 尝试将 0x4000000000000000 常量移至内存 该常量在 ieee 754 标准双精度中应等于 2 0 我正在使用的代码是 define two 0x4000000000
  • 32位PPC rlwinm指令

    我在理解上有点困难rlwinmPPC 汇编指令 旋转左字立即然后与掩码 我正在尝试反转函数的这一部分 rlwinm r3 r3 0 28 28 我已经知道什么了r3 is r3在本例中是一个 4 字节整数 但我不确定这条指令到底是什么rlw
  • 何时可以重用avx指令中的源寄存器

    在 avx 指令中用作源的寄存器何时可以在指令开始处理后重用 例如 我想使用vgatherdps该指令消耗两个 ymm 寄存器 其中之一是位移索引 我意识到vgatherdps由于数据的局部性较差 因此需要花费大量时间来收集 位移索引寄存器
  • Grub 和进入实模式(低级汇编语言编程)

    我一直在开发一个玩具操作系统 并一直使用 grub 作为我的引导加载程序 最近尝试使用 VGA 时 我发现无法使用硬件中断 我发现这是因为我被 grub 置于保护模式 有人知道如何在不删除 grub 的情况下回到实模式吗 如果您使用 GRU
  • 无法识别的仿真模式:MinGW32 上的 elf_i386

    我正在尝试制作内核 但无法链接C与程序集一起输出 这ld 我收到错误 无法识别的仿真模式 elf i386 我正在使用 Windows 10 专业版以及 MinGW32 和 MSYS 我正在使用的代码 link ld link ld OUT
  • 将字段中的位扩展到掩码中所有(重叠+相邻)集位的最快方法?

    假设我有 2 个名为 IN 和 MASK 的二进制输入 实际字段大小可能是 32 到 256 位 具体取决于用于完成任务的指令集 每次调用时两个输入都会改变 Inputs IN 1100010010010100 MASK 000111101

随机推荐

  • 如何在后台运行 Windows Phone 应用程序?

    我想知道 Windows Phone 应用程序是否可以在后台运行 我学过http msdn microsoft com en us library ff431744 v vs 92 aspx 在那里我找到了有关后台文件传输 代理和警报的信息
  • JavaScript 内部的国际化

    我有一个 JSP 页面 它接受超过 23 种语言的用户字符串 所以一个说英语的用户写道8 5 JavaScript 函数应该接受它以及输入8 5来自俄罗斯用户 在这种情况下 我们如何验证所有语言的 JavaScript 输入 您可能可以使用
  • PHP strtotime 错误(有时)?

    我在我的 PHP 代码中遇到了 strtotime 的问题 有时它是错误的 仅对于某些时区 而对于其他时区来说它是正确的 我无法理解它 我已经设置了也在我的页面顶部 但这没有帮助 基本上它的作用是添加或减去offset 3600值到设定时间
  • 迭代多个查询并将其存储在 pyspark dataframe 中

    我在 hive 中有一个表 我想根据循环中的条件查询它 并将结果动态存储在多个 pyspark 数据帧中 基本查询 g1 select from db hive table where group 1 group 1 spk sql g1
  • Javascript 如何匹配回调函数中的参数?

    我刚开始学习JavaScript 回调函数似乎很难理解 我的一个问题是javascript如何匹配回调函数中的参数 例如在以下 forEach 循环中 var friends Mike Stacy Andy Rick friends for
  • 如何迭代两个列表?

    我正在尝试在 pyGTk 中做一些事情 我构建了一个 HBox 列表 self keyvalueboxes for keyval in range 1 self keyvaluelen self keyvalueboxes append g
  • Angular.js:如何为所有应用程序控制器调用一次服务

    我不知道这是否是 Angular 概念之一或可能做到的 但我有一项调用用户信息 姓名 id 年龄 的服务 factory me function resource API URL q return getUser function var
  • Java Swing:多个窗口[关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 目前不接受答案 我是 GUI 编程新手 但需要创建一个多窗口 GUI 有谁知道有什么好的在线教程吗 或者您能否展示一个可以启动 2 个窗口的简单代码 只需创建两个
  • 如何在 O(n) 或 O(nlogn) 中找到包含重复项的最长非递减子序列?

    我们知道有一种算法可以在 O nlogn 中找到最长递增子序列 我想知道我们是否能找到时间复杂度相似的最长非递减子序列 例如 考虑一个数组 4 10 4 8 9 最长的递增子序列是 4 8 9 最长的非递减子序列是 4 4 8 9 首先 这
  • GUI 以 30 fps 运行?

    在测试一些使用 Swingworker 的实时模拟代码时 我注意到我的 GUI 似乎总是以 30 fps 运行 不多也不少 每次用户与应用程序交互 如鼠标移动 或调用 Swingworker 的 process 方法时 我都会更新 GUI
  • 如何从 C++ 将字符串矩阵传递到 Cuda 内核

    Problem 我有一个 C 矩阵 里面充满了字符串 我想将它传递给 cuda 内核函数 我知道 CUDA 无法处理字符串 因此经过一些研究 我尝试了下面列出的一些解决方案 尝试 在 C 中定义一个指针数组 其中每个单元格包含一个指针字符
  • JavaScript:将 ex 转换为 px

    所以我正在阅读 elem style width 并得到类似 3 1415926ex 的内容 我想将其转换为 px JavaScript 是否有内置函数来执行此操作 我更喜欢砍掉字符串的最后 2 个字母 将其读取为数字 然后将其乘以一个魔法
  • Qt3d:应用 Qt3DRender::QLayerFilter 时显示的工件

    我正在尝试使用图层过滤 如图所示这个答案 为此 我编写了一个简单的测试 见下文 这是question 在红色球体的某个位置 会出现伪影 看起来像是另一个摄像机在坐标 0 0 0 0 0 0 中的显示 See screen 在我的示例中 可以
  • 防止文本框在更新时返回到文本框的开头

    有没有办法让文本框在更新时冻结其位置 我每 1 秒更新一次 TKinter 中的文本框 但显示一些不断变化的信息 但是 我不希望文本框在更新时返回到文本框的开头 每次更新后 我都被迫快速向下滚动文本框以查看某些数据的更改 Defined a
  • Tailwind的config中,添加属性到主题VS theme.extend有什么区别?

    Tailwind 的配置文档多次使用了extend属性 但没有阐明在其上进行自定义的区别theme财产VStheme extend财产 module exports content src html js theme colors blue
  • 使用不同参数 testng 顺序执行多个测试

    我试图使用数据提供程序按顺序运行具有不同参数的多个测试 基本上场景是假设有 5 个测试完成测试流程 并且所有测试用例都应按顺序运行假设在数据提供程序中返回的第一个参数是 air 然后所有 5 个测试应该使用参数 air 运行 然后是第二个参
  • 在OpenGL中绘制多个三角形

    我刚刚开始使用 OpenGL 并且已经制作了自己的用 C 绘制三角形的 OOP 版本 我正在使用 glfw 和 glew 如果这很重要的话 我不明白为什么我不能画超过 1 个三角形 这是主要功能 int main Graphics Wind
  • 打开 Bootstrap Modal 以在 Ruby on Rails 中编辑记录

    我有一个 用户 模型 我在用户索引页面上有一个用户列表 每个用户旁边都有一个编辑按钮 我想单击每个用户的编辑按钮 这将打开引导模式 在引导模式上 我想显示可以编辑的用户记录 编辑表单将来自 form html erb 部分 它将用于新的和编
  • Facebook Messenger 的自定义 URI 方案

    鉴于近期 鼓励 由 Facebook 迁移到单独的即时通讯应用程序 并作为 信息非常丰富 回答有关 Facebook 应用程序支持的 URL URI 方案的问题 我一直想知道有关 Facebook Messenger 应用程序的信息是否自定
  • 有没有办法将寄存器文件视为 ARMv8 中的数组(标量或 Neon)?

    假设我有一个短数组v说 8int64 t 我有一个算法需要访问该数组的不同元素 这些元素不是编译时常量 例如就像是v i j 2 其中i and j是不受任何类型的常量传播影响的变量 通常 我会保留内存中的数组 计算数组索引 从内存中的该位