_mm_storeu_ps 的 AVX 等效项?

Posted

技术标签:

【中文标题】_mm_storeu_ps 的 AVX 等效项?【英文标题】:AVX equivalent for _mm_storeu_ps? 【发布时间】:2015-03-29 17:20:07 【问题描述】:

我有一个相当快的 AVX 代码,但它只是一个使用 AVX 的单一功能,大型项目的其余部分在 SSE2 上,所以我不想将架构设置为 AVX。在每次迭代结束时,我需要将一个 YMM 寄存器中的 4 个双精度数转换为 4 个浮点数并像这样存储它:

__m256d y = ......;
_mm_storeu_ps((float*)dst + i, _mm256_cvtpd_ps(y));

但 MSVC 正在使用 movups(不带“v”前缀)生成 SSE2 代码。有没有办法强制它只使用一条 AVX 指令?在我看来,唯一知道的方法是使用 AVX 作为目标,这似乎很荒谬。我只想在一个周期内利用 AVX。英特尔编译器显然理解它,因为我使用的是 AVX 自动调度,所以它在那里工作得很好,但通常英特尔编译器现在似乎没有办法去,它很慢而且代码比 MSVC 差,好吧,除了这个.. .

【问题讨论】:

【参考方案1】:

_mm_storeu_ps(float*,_mm128) 的 AVX 等效项是 _mm256_storeu_ps(float*,_mm256)。首先,AVX 是一个指令集。这意味着 CPU 必须在物理上拥有寄存器空间和 FPU 前端才能使用它们。换句话说,给予非 AVX 处理器的 AVX 将无法运行。您必须使用 /arch -AVX 进行编译,因为它是最新的,并且向后兼容 sse,sse2,sse3,ssse3,sse4,sse,sse4.1,sse4.2 但反之则不然。一个 AVX CPU 实现了所有的 sses,但 AVX 是一个与 sse CPU 无关的指令集。

由于 CPURAM 带宽不足,内存操作不是特别可大规模优化。如果您使用的是非常大的阵列,那么您将看不到 SSE4 loadu 和 AVX loadu 之间的细微差别,一条 6 车道的高速公路只能处理 X 多辆汽车,无论您一次要求多少辆汽车时间。当您可以将加载它们的延迟隐藏在其他工作之后时,较小的数组往往不会出现这种情况。您不应该交换 AVX 指令和 SSE,这不仅是因为设计复杂性,还有内部 cpu 复杂性。

此外,您不希望将 FPU 状态从 AVX 更改为 SSE,因为这本身会导致大多数人没有考虑到的性能开销。要么有一个代码的大同源部分处于一种状态(SSE,AVX),要么拥有所有 SSE 或 AVX

语法警告我不会语法

【讨论】:

我知道,如果 AVX 是可能的,我正在执行我自己的检测。我的问题是,是否有办法让编译器生成使用 XMM 寄存器而不是 YMM 的 AVX 前缀指令!我想写 4 个浮点数,而不是 8 个。这完全是为了避免 AVX->SSE 开关惩罚。 如果你想写 4 个浮点数并且你的代码的主体是 SSE 代码,那么我不明白你为什么希望这有点是 AVX。如果您只想写 4 个浮点数,请使用掩码存储操作,或者如果稍后再覆盖一些信息。但另一方面,带有 AVX 的处理器只有 YMM 寄存器,XMM0-XMM7 被重命名为 YMM0-YMM7。因此,如果您看到反汇编与这些寄存器一起玩,那实际上是同一件事。 蒙面商店,有趣,我去看看,虽然我听说这些蒙面指令非常非常慢。

以上是关于_mm_storeu_ps 的 AVX 等效项?的主要内容,如果未能解决你的问题,请参考以下文章

AVX2 等效于 std::clamp

iOS 设备的 ARM __clear_cache 等效项

如何使用 avx 指令将 float 向量转换为 short int?

__attribute__ ((warn_unused_result)) 的 Visual Studio 等效项

Deno 中的 Node.js 的 __dirname 和 __filename 等效项

Mac OS X 下的 _wfopen 等效项