【发布时间】:2019-06-23 20:48:52
【问题描述】:
我正试图围绕对已加载或尚未加载到寄存器中的内在类型的内存访问。
假设一些 SIMD 函数接受对浮点数组的引用。例如,
void do_something(std::array<float, 4>& arr);
void do_something_else(std::array<float, 4>& arr);
每个函数首先将数据加载到寄存器中,执行其操作,然后将结果存储回数组中。假设以下 sn-p :
std::array<float, 4> my_arr{0.f, 0.f, 0.f, 0.f};
do_something(my_arr);
do_something_else(my_arr);
do_something(my_arr);
c++ 编译器是否优化了函数调用之间不必要的加载和存储?这还重要吗?
我见过将__m128 类型包装在结构中并在构造函数中调用加载的库。当您将这些存储在堆上并尝试在它们上调用内部函数时会发生什么?例如,
struct vec4 {
vec4(std::array<float, 4>&) {
// do load
}
__m128 data;
};
std::vector<vec4> my_vecs;
// do SIMD work
您是否必须在每次访问时加载/存储数据?或者这些类应该声明一个私有的operator new,这样它们就不会存储在堆上?
【问题讨论】:
-
您可以在godbolt 上看到任何
C++代码的生成程序集。您可以选择一些编译器并使用优化标志。 -
C++ 中的引用是保证的非空指针。所以你真的只传递一个指针。除非它们是内联的,否则编译器不会优化函数的加载和存储。
-
std::vector的 SIMD 类型是 a dangerous pattern -
@harold 假设向量正确对齐(@987654331@ 或自定义分配器),您是否必须为每个操作加载/存储在寄存器中?例如:scc.ustc.edu.cn/zlsc/tc4600/intel/2017.0.098/compiler_c/common/…
+=是否总是加载到寄存器中?这不是超级慢吗? -
@scx 也许,也许不是,但为什么要冒险呢?您可以在需要时加载/存储,并使用
__m128进行主要计算