首页 > 编程问答 >如何优化这种简单的多值 simd 溅射/广播?

如何优化这种简单的多值 simd 溅射/广播?

时间:2024-06-06 12:24:50浏览次数:34  
标签:rust avx512

我想将一些 u8 扩展为 u64 ,但我想要的不是直接支持的零扩展或符号扩展,而是 "复制扩展"。有什么好办法可以做到这一点(在使用 avx512 的 intel cpus 上)?示例代码使用的是 rust 语言,但宿主语言并不是最有趣的部分。

#![feature(portable_simd)]#!

使用 std::simd::*;

// 将每个输入字节扩展 8 次
pub fn batch_splat_scalar(x: [u8; 16]) -> [u64; 16] {
  let mut ret = [0; 16];
  for i in 0.16 {
    ret[i] =
      u64::from_le_bytes([x[i], x[i], x[i], x[i], x[i], x[i], x[i], x[i], x[i], x[i], x[i]]);
  }
  返回
}

pub fn batch_splat_simd(x: u8x16) -> u64x16 {
  Simd::from_array(batch_splat_scalar(x.to_array()))
}
在使用 avx512 时,编译结果如下

所示
 vpmovzxbq zmm0, qword ptr [rsi] vpbroadcastq zmm0.
        vpbroadcastq zmm1,qword ptr [rip + .LCPI0_0] 
代码
        mov rax, rdi
        vpmuludq zmm2、zmm0、zmm1
        vpbroadcastq zmm3,qword ptr [rip + .LCPI0_1] vpmuludq zmm0,zmm0,zmm1
        vpmuludq zmm0, zmm0, zmm3
        vpsllq zmm0,zmm0,32
        vporq zmm0,zmm2,zmm0
        vmovdqu64 zmmword ptr [rdi],zmm0
        VPMOVZXBQ ZMM0,QWORD Ptr [RSI + 8]
        VPMULUDQ ZMM1,ZMM0,ZMM1
        vpmuludq zmm0, zmm0, zmm3
        VPSLLQ ZMM0,ZMM0,32
        VPORQ ZMM0、ZMM1、ZMM0
        vmovdqu64 zmmword ptr [rdi + 64],zmm0
        vzeroupper
        返回

https://godbolt.org/z/67cW5GnKf


是对的,生成的汇编代码对于执行复制扩展来说过于复杂。编译器没有选择最优的指令序列。

以下是一些使用 AVX-512 在 Rust 中对 u8 进行复制扩展到 u64 的更有效方法:

1. 使用 _mm512_broadcastb_epi64 intrinsics:

此 intrinsics 将一个字节广播到 64 位值的低 8 位。然后,可以使用移位和 OR 操作将广播的字节复制到 64 位值的所有字节。

#[target_feature(enable = "avx512f")]
unsafe fn batch_splat_simd_avx512(x: u8x16) -> u64x16 {
    let broadcasted = _mm512_broadcastb_epi64(x.as_i32() as _);
    // 创建一个掩码,其中每个字节都设置为 0x0101010101010101
    let mask = _mm512_set1_epi64(0x0101010101010101);
    // 将广播的值乘以掩码
    let expanded = _mm512_mul_epu64(broadcasted, mask);
    transmute(expanded)
}

2. 使用 vpbroadcastd 和 shuffle 指令:

此方法使用 vpbroadcastd 将每个字节广播到 32 位值。然后,使用 vpshufb 指令将 32 位值交错,生成所需的 64 位值。

#[target_feature(enable = "avx512f")]
unsafe fn batch_splat_simd_avx512_shuffle(x: u8x16) -> u64x16 {
    let broadcasted = _mm256_broadcastd_epi32(x.as_i32() as _);
    // 创建一个 shuffle 掩码,用于交错 32 位值
    let shuffle_mask = _mm256_set_epi8(
        15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0,
        15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0,
    );
    // 使用 shuffle 掩码交错广播的值
    let shuffled = _mm256_shuffle_epi8(broadcasted, shuffle_mask);
    transmute(_mm512_castps256_ps512(shuffled))
}

这些方法应该比最初的代码生成更有效的汇编代码。请注意,这些示例使用 unsafe 代码,因为它们使用 intrinsics 和假设对齐的内存访问。在生产代码中使用这些函数之前,请确保了解其含义。

此外,请务必使用 #[target_feature(enable = "avx512f")] 属性来启用 AVX-512 优化。

标签:rust,avx512
From: 78584042

相关文章

  • 【Docker】docker-compose文件快速部署RustDesk远程桌面平替TeamViewer
    1.服务器安装Docker服务2.创建docker-compose.yaml文件version:'3'networks:rustdesk-net:external:falseservices:hbbs:#RustDeskID/Rendezvous服务器container_name:hbbsports:-21115:21115#用于NAT类型测试的TCP......
  • Zero Trust Networks【7】
    一、了解应用程序管道二、TrustingSourceCode三、TrustingBuilds四、信任分配五、人在循环中六、信任一个实例七、运行时安全性八、安全软件开发生命周期(SDLC)九、保护应用程序和数据的隐私十、场景演练Chapter7.TrustingApplications硅谷著名投资者马克·安德......
  • Zero Trust Networks【5】
    一、BootstrappingTrust二、正在使用控制平面进行身份验证的设备三、存货[库存]管理四、更新和测量设备的信任关系五、软件配置管理六、使用设备数据进行用户授权七、TrustSignals八、场景演练Chapter5.TrustingDevices在零信任网络中信任设备是极其关键的;这也是......
  • Zero Trust Networks【4】
    一、AuthorizationArchitecture二、Enforcement三、PolicyEngine四、TrustEngine五、DataStores六、场景演练Chapter4.MakingAuthorizationDecisions授权可以说是发生在零信任网络中的最重要的过程,因此,做出授权决策不应该轻易采取。每一个流程和/或请求最终都将......
  • 改进rust代码的35种具体方法-类型(二十)-避免过度优化的诱惑
    上一篇文章-改进rust代码的35种具体方法-类型(十九)-避免使用反射“仅仅因为Rust允许您安全地编写超酷的非分配零复制算法,并不意味着您编写的每个算法都应该是超级酷的、零复制和非分配的。”-trentj   这本书中的大多数项目都旨在帮助现有程序员熟悉Rust及其成语。......
  • Zero Trust Networks【3】
    一、WhatIsanAgent?二、HowtoExposeanAgent?Chapter3.Context-AwareAgents想象一下,你正处在一个有安全意识的组织中。每个员工都有一台经过高度认证的笔记本电脑来完成他们的工作。随着今天的工作和个人生活的融合,一些人还想在手机上查看他们的电子邮件和日历。在......
  • Zero Trust【1】
    Chapter1.ZeroTrustFundamentals在一个网络监控无处不在的时代,我们发现很难信任任何人,而定义信任本身也同样困难。我们能相信,我们的互联网流量将是安全的,不会被窃听吗?当然不是!那你租用光纤的供应商呢?或者是昨天在你的数据中心处理电缆的合同技术人员?像爱德华·斯诺登和马克·......
  • 黑客团伙利用Python、Golang和Rust恶意软件袭击印国防部门;OpenAI揭秘,AI模型如何被用于
    巴黑客团伙利用Python、Golang和Rust恶意软件袭击印度国防部门!与巴基斯坦有联系的TransparentTribe组织已被确认与一系列新的攻击有关,这些攻击使用Python、Golang和Rust编写的跨平台恶意软件,针对印度政府、国防和航空航天部门。“这一系列活动从2023年底持续到2024年4月......
  • Rust中的CLI程序
    100编程书屋_孔夫子旧书网技术的学习从不会到会的过程是最有意思的,也是体会最多的。一旦熟练了,知识变成了常识,可能就失去了记录学习过程的最佳时机。在我看来学习一门计算机语言和学习人类语言有很多共通之处。我们学习人类语言是从单个的词开始,然后是简单句子,通过不断的与......
  • 在 Rust 多线程应用程序中锁定 Mutex 时发生死锁
    我正在开发一个Rust应用程序,其中有一个与PacketManager交互的BusDevice。在多线程环境中尝试锁定一个Mutex时,我遇到了死锁。应用程序被卡在锁定Mutex的那一行,再也无法继续。详细描述:在我的Rust应用程序中,我有一个使用PacketManager发送确认数据包的BusDevice。BusD......