ARM/neon memcpy 针对*未缓存*内存进行了优化?

2023-12-26

我使用的是基于 Xilinx Zynq 7000 ARM 的 SoC。我正在努力处理 DMA 缓冲区(需要帮助映射 Xilinx/ARM SoC (Zynq 7000) 上的预留 **可缓存** DMA 缓冲区 https://stackoverflow.com/questions/34884313/need-help-mapping-pre-reserved-cacheable-dma-buffer-on-xilinx-arm-soc-zynq),所以我追求的一件事是更快的 memcpy。

我一直在考虑使用 Neon 指令和内联汇编为 ARM 编写更快的 memcpy。无论 glibc 有什么,它都很糟糕,尤其是当我们从 ucached DMA 缓冲区复制时。

我从各种来源整合了自己的复制功能,包括:

  • 快速 ARM NEON memcpy https://stackoverflow.com/questions/11161237/fast-arm-neon-memcpy
  • gcc 中的 arm 内联汇编 https://stackoverflow.com/questions/9302575/arm-inline-assembly-in-gcc
  • http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka13544.html http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka13544.html

对我来说主要的区别是我试图从uncached缓冲区,因为它是 DMA 缓冲区,并且 ARM 对缓存 DMA 缓冲区的支持不存在。

这就是我写的:

void my_copy(volatile unsigned char *dst, volatile unsigned char *src, int sz)
{
    if (sz & 63) {
        sz = (sz & -64) + 64;
    }
    asm volatile (
        "NEONCopyPLD:                          \n"
        "    VLDM %[src]!,{d0-d7}                 \n"
        "    VSTM %[dst]!,{d0-d7}                 \n"
        "    SUBS %[sz],%[sz],#0x40                 \n"
        "    BGT NEONCopyPLD                  \n"
        : [dst]"+r"(dst), [src]"+r"(src), [sz]"+r"(sz) : : "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "cc", "memory");
}

我做的主要事情是省略预取指令,因为我认为它在未缓存的内存上毫无价值。

与 glibc memcpy 相比,这样做的速度提高了 4.7 倍。速度从大约 70MB/秒增加到大约 330MB/秒。

不幸的是,这远不如缓存内存中的 memcpy 快,系统 memcpy 的运行速度约为 720MB/秒,Neon 版本的运行速度约为 620MB/秒(可能会慢一些,因为我的 memcpy 可能不进行预取)。

谁能帮我弄清楚我可以做些什么来弥补这种性能差距?

我尝试过很多方法,例如一次复制更多、两次加载然后两次存储。我可以尝试预取只是为了证明它没有用。还有其他想法吗?


如果您尝试进行大型、快速传输,缓存内存通常会优于未缓存内存,但正如您所指出的,对缓存 DMA 缓冲区内存的支持必须在某个地方进行管理,并且在

我对你的设计假设有两件事:

  • 用户空间正在读取内存映射的硬件缓冲区
  • 从 FGPA 到 CortexA9 VIC/GIC 存在某种信号/事件/中断,通知 CortexA9 何时有新的缓冲区可供读取。

将 DMA 缓冲区与缓存行边界对齐,并且不要在 DMA 缓冲区末尾和下一个缓存行之间放置任何内容。每当 FPGA 向 CPU 发出缓冲区已准备就绪的信号时,就会使高速缓存失效。

我认为 A9 没有一种机制来控制所有核心和层上的缓存行,因此您可能希望将执行此操作的程序固定到一个核心,以便您可以跳过维护另一个核心上的缓存。

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

ARM/neon memcpy 针对*未缓存*内存进行了优化? 的相关文章

  • 哪些变量类型/大小在 STM32 微控制器上是原子的?

    以下是 STM32 微控制器上的数据类型 http www keil com support man docs armcc armcc chr1359125009502 htm http www keil com support man d
  • ARM架构中不同处理器模式下如何使用内核堆栈?

    据我了解 每个进程都有一个用户堆栈和内核堆栈 除此之外 ARM 架构中的每种模式都有一个堆栈 所以我想知道不同的堆栈和堆栈指针在 ARM 模式下如何工作 另外 何时会使用与进程关联的内核堆栈 何时会使用与进程关联的内核堆栈 当您进行系统调用
  • 将 GCC 内联汇编与采用立即值的指令结合使用

    问题 我正在为 ARM Cortex M3 处理器开发定制操作系统 为了与我的内核交互 用户线程必须生成 SuperVisor Call SVC 指令 以前称为 SWI 用于软件中断 该指令在ARM ARM中的定义是 这意味着该指令需要即时
  • ARM Cortex A8 PMNC 读取在启用后也给出 0.. 有什么想法/建议吗?

    MODULE LICENSE GPL MODULE DESCRIPTION user mode access to performance registers int init arm init void unsigned int valu
  • 在嵌入式设备上使用new或malloc引起的段错误[关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 help reopen questions 我正在尝试
  • ARM + gcc:不要使用一大块 .rodata 部分

    我想使用 gcc 编译一个程序 并针对 ARM 处理器进行链接时间优化 当我在没有 LTO 的情况下编译时 系统会被编译 当我启用 LTO 时 使用 flto 我收到以下汇编错误 错误 无效的文字常量 池需要更近 环顾网络 我发现这与我系统
  • 分析 Cortex-M7 (stm32f7) 上的 memcpy 性能

    简洁版本 从 GNU ARM 工具链中提取的 memcpy 的性能指标在 ARM Cortex M7 上对于不同的副本大小似乎差异很大 即使复制数据的代码始终保持不变 这可能是什么原因造成的 长版 我是使用 GNU Arm 工具链 11 2
  • ARM 调用约定是否允许函数不将 LR 存储到堆栈中?

    正如标题所示 我在理解 ARM 架构的调用约定时遇到问题 特别是 我仍然很难知道当你调用子程序时 LR 寄存器会发生什么 我认为 当您进入子程序时 处理 LR 寄存器的最明显 最安全的方法是将其存储到堆栈中 但该行为没有出现在文档中 因此我
  • 了解 ctags 文件格式

    我使用 Exhuberant ctags 来索引我的 c 项目中的所有标签 c project 是 Cortex M7 微控制器的嵌入式软件 结果是一个标签文件 我正在尝试阅读该文件并理解所写的内容 根据我找到的 ctags 和 Exhub
  • 为什么当大小大于 50 时,该程序花费的时间会呈指数级增长?

    所以我正在为类编写一个 ARM 汇编快速排序方法 我对大部分内容都有了解 除了复杂性没有意义 我们将其与我们制作的另一种冒泡排序方法进行比较 它对于具有 1 个参数和 10 个参数的示例表现更好 然而 我什至无法比较 100 个参数测试 因
  • C memcpy 二维数组

    我正在尝试使用将一个二维数组复制到另一个memcpy 我的代码 include
  • 如何使用movntdqa避免缓存污染?

    我正在尝试编写一个 memcpy 函数 该函数不会将源内存加载到 CPU 缓存中 目的是避免缓存污染 下面的 memcpy 函数可以工作 但会像标准 memcpy 一样污染缓存 我正在使用带有 Visual C 2008 Express 的
  • 什么是遗留中断?

    我正在开发一个项目 试图弄清楚 ARM 架构的全局中断控制器中如何处理中断 我正在使用 pl390 中断控制器 我看到有一条线被称为传统中断 它绕过了分配器逻辑 假设有 2 个中断可以被编程为传统中断 任何人都可以帮助解释一下什么是遗留中断
  • 设备树不匹配:.probe 从未被调用

    我无法理解设备树的工作原理 或者具体来说为什么该驱动程序无法初始化 这是在 android 版本 3 10 的 rockchip 供应商内核中 驱动程序 看门狗 rk29 wdt c 为了可读性而减少 static const struct
  • 交叉编译armv5,但它创建v7二进制文件

    我设法为arm926ej s创建了一个目标文件我在 qemu 上使用 Debian Arm arm linux gnueabi gcc 4 4 static O c mcpu arm926ej s hello c o hello root
  • 如何在WinMobile6上启用ARMv6非对齐访问?

    ARMv6 引入了一个很棒的功能 未对齐的内存访问 这使得代码中的某些事情变得更加简单和更快 但微软只在winCE6中提供了API 现在大多数 PDA 都基于 WinMobile6 基于 CE 5 x 默认情况下禁用未对齐访问 我尝试在 C
  • ARM Cortex-M3 启动代码

    我试图了解 STM32 微控制器的 Keil realview v4 附带的初始化代码是如何工作的 具体来说 我试图了解堆栈是如何初始化的 In the 文档 http infocenter arm com help index jsp t
  • 为什么前向引用 ADR 指令在 Thumb 代码中以偶数偏移进行汇编?

    To bx对于 Thumb 函数 需要设置地址的最低有效位 GNU 作为文档states https sourceware org binutils docs as ARM Opcodes html当地址是从一个生成时这是如何工作的adr伪
  • .ko 文件是如何构建的

    我正在尝试将我自己的驱动程序移植到Beagle 板 xm arm cortex A8 在移植时我试图弄清楚如何 ko文件实际构建 在我们的Makefile我们只有一个命令来构建 o file 怎样是一个 ko文件已建立 使用Linux 2
  • GCC:如何在 MCU 上完全禁用堆使用?

    我有一个在基于 ARM Cortex M 的 MCU 上运行并用 C 和 C 编写的应用程序 我用gcc and g 编译它并希望完全禁用任何堆使用 在 MCU 启动文件中 堆大小已设置为 0 除此之外 我还想禁止代码中意外使用堆 换句话说

随机推荐

  • 为什么在使用 MSpec/Moq 测试此异步方法时会收到 NullReferenceException?

    我想测试异步方法是否返回正确的类型 此方法使用依赖类中的另一个异步方法 依赖类实现此接口 Task
  • 在 dotnet core SDK 版本之间切换

    我最近安装了 VS 2017 RC 然后我的 dotnet 版本自动指向1 0 0 preview4 004233 因此 每当我使用命令创建新项目时dotnet new t Console我看不见project json虽然我看到 cspr
  • 如何在quarkus microprofile案例中配置rest客户端

    当使用 Quarkus microprofile 作为 REST 客户端时 如何配置底层 HttpClient 比如重试次数 每个主机的连接池大小等等 另外是否可以以某种方式强制客户端重新启动 因此连接池将重新启动 https downlo
  • 转发器内动态控件的视图状态问题

    最近 我在使用要添加动态控件的中继器时遇到了一个问题 虽然我有一个解决方法 在功能上完全符合我想要的功能 但我想知道是否有更好的方法为了我的理解 我使用 ASP NET 已经有大约 6 个月了 每次我认为我已经掌握了页面生命周期 视图状态时
  • 使用expect脚本从远程机器执行ssh

    我是expect脚本的新手 并且有一个用例 在该用例中 我需要从已经使用expect脚本完成ssh的机器上执行ssh 这是我的代码片段 usr bin expect f set timeout 60 spawn ssh email prot
  • 向 Google 地图添加多个标记

    我希望为 Google 地图 v3 API 中列出的每个商家添加标记在本页 http www inside guides co uk brentwood shops and shopping clothes shops html在右上角 我
  • 按列值动态过滤 jTable

    我需要根据特定列中的值动态过滤 JTable 因此 如果我有 2 列 例如 国家 地区 和 首都 我只想按 国家 地区 列进行过滤 我通过实现以下代码找到了问题的部分解决方案 import java awt BorderLayout imp
  • 在 t.string 的预定义值中进行选择

    是否有可能创建一个 collection select or select tag for a t string 用户可以在哪里选择字符串的预定义值 并且只允许将那些值存储在字符串的数据库中 例如 t string relationship
  • 使“gradle javadoc”任务与 Java 9 一起工作

    我有一个使用 source target 1 9 1 9 的多模块 Gradle Java 项目 有两个模块 my base and my dependsOnBase The my base模块没有其他依赖项 module my base
  • Spring 中的 ElasticSearch 与 @Query

    我已经使用 ElasticSearch 的 plugin head 接口成功创建了一个查询 该查询旨在返回特定位置的特定设备的最新时间戳 该查询如下所示 query bool must term deviceevent location i
  • 如何在 Bash 中拆分带引号的字符串?

    很少有问题 https stackoverflow com questions 918886 how do i split a string on a delimiter in bash关于如何通过给定分隔符拆分 Bash 脚本中的字符串有
  • android android.provider.MediaStore.ACTION_VIDEO_CAPTURE 返回 null onActivityResult 与 Nexus 7

    我正在使用意图来录制视频 所以我在 recordVideo 按钮的单击上使用以下代码 Videofilepath Intent intent new Intent android provider MediaStore ACTION VID
  • 在公共存储库中隐藏密钥

    我正在开发一个开源 JavaScript 应用程序 我正在尝试与第三方 API 特别是 github 进行交互 我试图将整个应用程序保留在客户端 所以我真的没有服务器可以回退或存储隐藏文件 作为 OAuth 流程的一部分 我需要提供为我的
  • 时间选择器显示时间为 4:7 而不是 04:07

    我有一个时间选择器功能 可以在 EditText 中设置时间 但它显示的格式不合适 例如 04 07pm 显示为 4 7 当时间中的数字小于 10 时 它会自动删除 0 请帮帮我 我的代码是 if v btnTimePicker1 Proc
  • 选择使用 IIS 的 WCF 服务托管或使用 Windows 服务的自托管

    因为我们想要使用 Asp Net MVC 3 开发一个新产品 这里的关键点是我们通过 WCF Web 服务与数据库对话的所有内容 我们正处于需要决定是在 IIS 中托管 WCF Web 服务还是使用 Windows 服务自托管的阶段 我提出
  • 带有滚动条的文本区域的圆角

    在我的网站上我有一个 htmltextarea框中有大量文本 因此它有一个滚动条 好吧 我想在我的文本区域上有圆角 但是滚动条看起来很糟糕 这是我的 HTML 片段
  • 变量名长度对 C# 性能重要吗?

    我一直想知道在 WinForms C 中使用长描述性变量名称是否对性能有影响 我问这个问题是因为在 AutoIt v3 解释语言 中提出了具有短名称的变量 例如aa代替veryLongVariableName速度要快得多 当程序大于 5 行
  • 弹簧接线,单例与原型

    刚刚阅读了 spring 的内容 当在 spring 中使用 DI 时 如果将 bean 设置为单例 默认 则将 分配 该类的单个实例 而原型每次都会强制创建一个新实例 每次容器分配相同的实例会产生什么后果 这是否意味着会有共享状态 也就是
  • 无法使用 Excel Interop 安排程序

    我用 C NET 开发了一个控制台程序 它使用 Excel Interop 如果我从命令行运行该程序 则该程序在我的开发计算机和 Windows Server 2008 中运行得很好 当我尝试安排任务每天运行时 我收到了这个恼人的互操作错误
  • ARM/neon memcpy 针对*未缓存*内存进行了优化?

    我使用的是基于 Xilinx Zynq 7000 ARM 的 SoC 我正在努力处理 DMA 缓冲区 需要帮助映射 Xilinx ARM SoC Zynq 7000 上的预留 可缓存 DMA 缓冲区 https stackoverflow