Visual Studio 2017:_MM_LOAD_PS经常被编译为移动
Visual Studio 2017: _mm_load_ps often compiled to movups
我正在查看我的代码生成的汇编(使用Visual Studio 2017),并注意到_mm_load_ps经常(总是?)汇编为移动。
我正在使用_mm_load_ps上的数据是这样定义的:
struct alignas(16) Vector {
float v[4];
}
// often embedded in other structs like this
struct AABB {
Vector min;
Vector max;
bool intersection(/* parameters */) const;
}
现在,当我使用此构造时,将会发生以下内容:
// this code
__mm128 bb_min = _mm_load_ps(min.v);
// generates this
movups xmm4, XMMWORD PTR [r8]
我期望由于载体(16)而引起动作。在这种情况下,我还需要其他内容来说服编译器使用动作吗?
编辑:我的问题与这个问题有所不同,因为我没有崩溃。该结构是专门对齐的,我还使用对齐分配。相反,我很好奇编译器为什么要切换_mm_load_ps(对齐内存的固有语言)将其切换到移动。如果我知道struct是在一个对齐的地址分配的,并且我通过此*来称呼它*是安全的,对吗?
在最新版本的Visual Studio和Intel编译器(最近作为2013年后?)上,编译器很少会生成Aligned Simd Load/Stores。
。用于AVX或更高版本时:
- Microsoft编译器(> VS2013?)不会生成对齐负载。但它仍然会生成对齐的商店。
- 英特尔编译器(> Parallel Studio 2012?)根本不再这样做。但是您仍然会在其手工优化库中的ICC编译的二进制文件中看到它们,例如
memset()
。 - 从GCC 6.1开始,当您使用对齐的固有时,它仍然会生成对齐的负载/存储。
允许编译器执行此操作,因为当正确编写代码时,它不是功能损失。从Nehalem开始的所有处理器都没有对地址对齐时对未对准负载/商店的罚款。
微软在此问题上的立场是"通过不崩溃来帮助程序员"。不幸的是,我再也找不到Microsoft的原始来源了。我认为,这与此相反,因为它隐藏了未对准的惩罚。从正确的角度来看,它也隐藏了不正确的代码。
无论是什么情况,都无条件地使用Unigned Load/Stores会简化编译器。
新相关性:
- 启动并行工作室2018,英特尔编译器根本不再产生对齐的动作 - 即使对于预纳哈勒姆的目标也是如此。
- 从Visual Studio 2017开始,Microsoft编译器也根本不再生成对齐的动作 - 即使针对AVX预备硬件。
这两种情况都会导致较旧的处理器的不可避免的性能降解。但这似乎是故意的,因为英特尔和微软都不再关心旧处理器。
唯一免疫此免疫的载荷/存储固有是非阶梯载荷/存储。它们没有不一致的等同,因此编译器别无选择。
因此,如果您只想对代码的正确性进行测试,则可以在Load/Store Intrinsics中代替非时空的代码。但是,请注意不要让类似的东西进入生产代码,因为NT负载/商店(尤其是NT商店)是一把双刃剑,如果您不知道自己在做什么,可能会伤害您。
- std::vector::p ush_back() 不会在 MSVC 上编译具有已删除移动构造函数的对象
- std::任何只用于移动的模板,其中副本ctor内的static_assert等于编译错误,但为什么
- 编译对移动应用的影响?
- 初始化不可移动对象数组:为什么这样的代码无法在 GCC 上编译?
- 程序编译,但当分解为函数时实际上不会移动电机
- 提升移动编译错误
- 为什么删除移动构造函数会导致编译错误
- 将函数从控制台应用程序移动到共享库项目似乎会带来不相关的编译错误
- Visual Studio 2017:_MM_LOAD_PS经常被编译为移动
- 在向量中使用派生的可移动但不可压缩的会导致编译错误
- libstdc++已弃用;移动到libc++[-Wdeprecated],但是更改会产生编译错误
- 如果将功能的非常简单的定义移动到.cpp,则编译时间的减少是多少
- 只需添加任何事情都不会导致编译错误(围绕std ::移动),为什么
- 使用 pimpl 移动类无法编译
- 在Visual Studio中,我不想提交我的Debug文件夹,但它中有dll文件,如果我移动它,项目将无法编译
- 将 Windows C++ 项目从 Qt4 移动到 5 会给出数百个看似无关的编译错误
- 将模板方法移动到派生中断编译
- 返回仅移动类型编译,即使复制构造函数不可用
- 将错误从链接时移动到编译时
- C++ 移动构造函数无法编译