C 负载并存储优化和堆对象
C++ load and store optimizations and heap objects
我试图将头缠绕在内存访问固有类型的内存中,这些类型已加载到寄存器中。
假设一些simd函数接受引用对浮动数组的引用。例如,
void do_something(std::array<float, 4>& arr);
void do_something_else(std::array<float, 4>& arr);
每个功能首先将数据加载到寄存器中,执行其操作,然后将结果存储回数组。假设以下片段:
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
,因此它们不存储在堆中?
如果编译器与呼叫分开编译功能,则无法优化商店和加载。当函数在一个.cpp文件中,在另一个.cpp文件中调用和链接时间优化时,绝对是这种情况。
。但是,如果编译器
同时看到功能定义及其呼叫(或在链接时间优化期间(,
决定内联函数调用和
决定融合循环,
然后它可能会删除不必要的商店和负载。
注意,这三个点都不是微不足道的。程序员仅控制第一点,另外两个是由编译器酌情决定的100%。因此,您通常必须假设这种优化不会发生。如果您的功能实际上是模板(也可以确保满足点1(,那么将上升升起的机会有些机会,但是编译器是否真的将循环融合在您的控制范围内。
关于包含SIMD类型的结构:SIMD类型驻留在堆上是完全合法的。与在堆栈上分配的绝对没有区别。
但是,您不仅可以用__m128
别名std::array<float, 4>
,这会违反严格的别名规则。将std::array<float, 4>
重新解释为__m128
只能使用副本安全地进行(重新解释为char*
,副本,重新解释为__m128
(,否则允许您的编译器混合使用该数组和SIMD类型的访问。
- 空基优化子对象的地址
- 这个C++编译器优化(在自身的实例上调用对象自己的构造函数)的名称是什么,它是如何工作的?
- 具有小对象优化功能的智能指针
- 现代编译器会优化只引用对象子集的局部变量吗
- 根据 C++ 中的属性对对象类进行分区的优化方法
- 将空基类优化对象强制转换为另一种类型是否会破坏严格的别名?
- 编译器如何优化临时对象?
- 具有嵌套对象优化的 C++ emplace_back
- C 负载并存储优化和堆对象
- 线程上下文上的静态存储对象优化
- 在没有返回值优化的情况下将两个对象加在一起时,将创建多少个临时对象
- 在VS2017中编译错误C2027,但没有小对象优化
- 假设没有编译器优化,则将创建多少次此对象
- 有没有办法强制c++编译器不优化静态库中的特定静态对象
- 在小对象优化中调试崩溃以进行类型擦除
- 为什么普通的 c++ 编译器不优化对象复制?
- C++对象生存期优化
- 具有查找表的可选帮助的对象查找,如果未使用,则必须对其进行优化
- 为什么 C++ 自动对象优化发生在此代码中
- 是否有办法为永久对象优化shared_ptr ?< / h1 >