编译以下内联程序集:

#![feature(portable_simd)]

use std::simd::{i64x8, f64x8};
use std::arch::asm;


pub fn convert(a: i64x8) -> f64x8{
    let converted: f64x8;
    unsafe {
        asm!(
        "vcvtqq2pd {converted} {a}",
        a = in(zmm_reg) a,
        converted = out(zmm_reg) converted,
        );
    }
    converted
}


导致以下错误:

error: cannot use value of type `Simd<i64, 8>` for inline assembly
  --> <source>:12:25
   |
12 |         a = in(zmm_reg) a,
   |                         ^
   |
   = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly

error: cannot use value of type `Simd<f64, 8>` for inline assembly
  --> <source>:13:34
   |
13 |         converted = out(zmm_reg) converted,
   |                                  ^^^^^^^^^
   |
   = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly

error: aborting due to 2 previous errors

您将需要-C target-feature=+avx512f来编译以上内容.或者,请参阅this godbolt

这对我来说没有多大意义,因为inline assembly docs清楚地表明f64x8i64x8zmm_reg可以接受的输入类型.

此外,错误消息指出SIMD向量是可接受的,但这就是我输入的内容.

如果与此相关,则将其转载到:

active toolchain
----------------

nightly-x86_64-unknown-linux-gnu (default)
rustc 1.68.0-nightly (afaf3e07a 2023-01-14)

这是 rust 病还是我做错了什么?

推荐答案

正如注释中提到的,编译器还不支持在汇编(relevant issue)中使用可移植的SIMD类型.注意,并不是所有可移植的SIMD类型都可以发送到汇编,使用f64x16类型这样的事情是完全合法的,但我不知道任何支持的体系 struct 可以处理等价的类型.作为解决办法,可以使用特定于平台的矢量类型,例如__m512i__m512d.

#![feature(portable_simd)]
#![feature(stdsimd)]

use std::simd::{i64x8, f64x8};
use std::arch::asm;
use std::arch::x86_64::*;

pub fn convert(a: i64x8) -> f64x8{
    let a = __mm512i::from(a);
    let converted: __mm512d;
    unsafe {
        asm!(
        "vcvtqq2pd {converted}, {a}",
        a = in(zmm_reg) a,
        converted = out(zmm_reg) converted,
        );
    }
    converted.into()
}

Godbolt

当然,如果您要这样做,请尽可能使用适当的SIMD内部函数而不是汇编来编写代码,以帮助编译器优化代码.

Rust相关问答推荐

重新导出proc宏导致未解决的extern crate错误""

Box::new()会从一个堆栈复制到另一个堆吗?

防止cargo test 中的竞争条件

如何用Axum/Tower压缩Html内容?

零拷贝按步骤引用一段字节

如何修复&q;无法返回引用函数参数的值在异步规则中返回引用当前函数&q;拥有的数据的值?

使用Rust WASM读取文件

用于实现获取 struct 体 id 的特征规范

在什么情况下 `..._or()` 比 `..._or_else(|| {})` 更好,为什么?

我应该如何表达具有生命周期参数的类型的总排序,同时允许与不同生命周期进行比较?

如何对一个特征的两个实现进行单元测试?

是否可以在不直接重复的情况下为许多特定类型实现一个函数?

这个不安全的 Rust 代码有什么问题,所以它可以在 Windows 上运行,但不能在 Ubuntu 上运行?

为什么 Rust 创建的 f32 小于 f32::MIN_POSITIVE?

tokio::sync::broadcast::Receiver 不是克隆

Rust Option 的空显式泛型参数

返回迭代器的特征

如何在 Rust 中返回通用 struct

发生移动是因为 `data` 的类型为 `Vec`,它没有实现 `Copy` 特性

如何解析 Rust 中的 yaml 条件字段?