sse - 指向 AVX 加载结果的指针 (_mm256_load_si256)
问题描述
如果我有一些类的字段像__m256i* loaded_v
,以及像这样的方法:
void load() {
loaded_v = &_mm256_load_si256(reinterpret_cast<const __m256i*>(vector));
}
loaded_v
有效指针将持续多长时间?由于寄存器数量有限,我想最终loaded_v
会引用不同的值,或者会发生其他一些奇怪的行为。但是,我想减少我做的负载数量。
我正在编写一个打包位数组类,我想使用 AVX 内在函数来提高性能。然而,每次我做一些操作(和、或、异或等)时,加载我的位数组是低效的。因此,我希望能够load()
在执行一些操作之前显式调用。但是,我不明白 AVX 寄存器是如何处理的。任何人都可以帮助我,或者指向我有关此问题的一些文档吗?
解决方案
优化编译器会自动使用寄存器。
它可能将__m256
变量放入内存或寄存器中,或者可能在代码的一部分中使用寄存器,并将其溢出到另一部分中。这不仅可以使用独立的自动存储(堆栈)变量来完成,还可以使用类的成员来完成,特别是如果类实例本身就是一个自动存储变量。
在使用寄存器的情况下,__m256
变量将对应 ymm 寄存器之一(x86-64 中的 16 个,32 位编译中的 8 个之一,或 AVX512 的 x86-64 中的 32 个之一),无需间接引用它。
_mm256_load_si256
内在不一定编译vmovdqa
为. 例如,这段代码:
#include <immintrin.h>
__m256i f(__m256i a, const void* p)
{
__m256i b = _mm256_load_si256(reinterpret_cast<const __m256i*>(p));
return _mm256_xor_si256(a, b);
}
编译如下(https://godbolt.org/z/ve67YPn4T):
vpxor ymm0, ymm0, YMMWORD PTR [rdx]
ret 0
C 和 C++ 是高级语言;内在函数应该被视为向编译器传达语义的一种方式,而不是指令助记符。
您应该将值加载到变量中,
__m256i loaded_v;
loaded_v = _mm256_load_si256(reinterpret_cast<const __m256i*>(vector));
或临时:
__m256_whatever_operation(_mm256_load_si256(reinterpret_cast<const __m256i*>(vector)), other_operand);
您应该遵循通常的 C 或 C++ 规则。
如果您从指针重复加载间接值,将其缓存在变量中可能会有所帮助,以便编译器看到该值在加载之间没有变化,并将其用作优化机会。当然编译器无论如何都可能错过这个机会,或者即使没有缓存变量也能找到它(可能在严格的别名规则的帮助下)。
推荐阅读
- c# - 如何使用快捷键“Esc”关闭模型对话框
- vue.js - 使用 Vue 测试工具测试 Chart.js 组件会引发 window.matchMedia 错误
- python - TensorFlow:在每个时间步打印 RNN 的内部状态
- javascript - Javascript - 将输入存储在对象中,然后存储到数组中,然后显示在页面上
- regex - 灾难性回溯问题解决方案
- go - 水牛中的反向路由
- javascript - 打开带有外部锚链接的特定手风琴面板
- google-maps - 更新谷歌地图上的取货地点
- angular - 角度自动完成对象
- html - 如何将悬停限制为一次不适用于所有链接?