优化RGBA-> RGB arm64组件

 2449978963潇潇 发布于 2023-02-09 13:52

我写了这个非常天真的NEON实现,从RGBA转换为RGB.它有效,但我想知道我还能做些什么来进一步提高性能.

我尝试使用预取大小,然后再展开循环,但性能没有太大变化.顺便说一句,在预取的尺寸方面,是否有任何经验法则?我在网上找不到任何有用的东西.此外,在"ARMv8指令集概述"中,我看到还有一个存储预取,这有用吗?

目前我正在大约1.7ms转换iPhone5s上的1280x720图像.

// unsigned int * rgba2rgb_neon(unsigned int * pDst, unsigned int * pSrc, unsigned int count);
_rgba2rgb_neon:
    cmp     w2, #0x7
    b.gt    loop

    mov     w0, #0
    ret

loop:
    prfm    pldl1strm, [w1, #64]

    ld4.8b  {v0, v1, v2, v3}, [w1], #32
    ld4.8b  {v4, v5, v6, v7}, [w1], #32

    prfm    pldl1strm, [w1, #64]

    st3.8b  {v0, v1, v2}, [w0], #24
    st3.8b  {v4, v5, v6}, [w0], #24

    subs    w2, w2, #16
    b.gt    loop

done:
    ret

Stephen Cano.. 5

首先(因为我假设您的目标是iOS),vImage(Accelerate.framework的一部分)为您提供此转换,如vImageConvert_RGBA8888toRGB888.这具有可在所有iOS和OS X系统上使用的优点,因此您无需为arm64,armv7s,armv7,i386,x86_64编写单独的实现.

现在,可能是你自己编写这个转换作为练习,而不是因为你根本不知道一个已经可用.在这种情况下:

避免使用ld[34]st[34].它们很方便但通常比使用ld1和置换慢.

对于像这样的完全常规的数据访问模式,不需要手动预取.

加载四个16b RGBA矢量ld1.16b,用三个tbl.16b指令从中提取三个16b RGB矢量,然后存储它们st1.16b

或者,尝试使用非临时加载和存储(ldnp/ stnp),因为您的图像大小太大而无法放入缓存中.

最后,回答你的问题:存储的预取提示主要是有用的,因为某些实现可能会导致部分行写入错过高速缓存的显着停顿.对于任何错过缓存的写入,特别简单的实现可能会有停顿.

1 个回答
  • 首先(因为我假设您的目标是iOS),vImage(Accelerate.framework的一部分)为您提供此转换,如vImageConvert_RGBA8888toRGB888.这具有可在所有iOS和OS X系统上使用的优点,因此您无需为arm64,armv7s,armv7,i386,x86_64编写单独的实现.

    现在,可能是你自己编写这个转换作为练习,而不是因为你根本不知道一个已经可用.在这种情况下:

    避免使用ld[34]st[34].它们很方便但通常比使用ld1和置换慢.

    对于像这样的完全常规的数据访问模式,不需要手动预取.

    加载四个16b RGBA矢量ld1.16b,用三个tbl.16b指令从中提取三个16b RGB矢量,然后存储它们st1.16b

    或者,尝试使用非临时加载和存储(ldnp/ stnp),因为您的图像大小太大而无法放入缓存中.

    最后,回答你的问题:存储的预取提示主要是有用的,因为某些实现可能会导致部分行写入错过高速缓存的显着停顿.对于任何错过缓存的写入,特别简单的实现可能会有停顿.

    2023-02-09 13:55 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有