C :如何防止使用AVX进行初始化的默认构造函数
C++: How to prevent default constructor using AVX for initialisation
考虑以下内容:
// foo.h
class Foo
{
public:
int x = 2;
int y = 3;
void DoSomething_SSE();
void DoSomething_AVX();
// ( Implicit default constructor is generated "inline" here )
};
// Foo_AVX.cpp, compiled with -mavx or /arch:AVX
void Foo::DoSomething_AVX()
{
// AVX optimised implementation here
}
// Foo_SSE.cpp, compiled with -msse2 or /arch:SSE2
void Foo::DoSomething_SSE()
{
// SSE optimised implementation here
}
以下问题是:编译器将使用"内联"语义生成隐含的默认构造函数(注意:Inline Sponics dos not> not not 表示函数必定会被嵌入),并且 - 构造函数未夹住的情况 - 然后,链接器将选择一个实现并丢弃另一个。
如果链接器选择在AVX编译单元中生成的构造函数,则此代码将在不支持AVX的机器上使用非法指令崩溃。
可以通过放入明确的默认构造函数(__forceinline)(确保它是每个汇编单元的一次与一个汇总)或在标题中声明并在编译单元中定义的,该汇编单元以最低的常见,以最低的commo分母指令集。
但是,肯定有一种方法可以获取语言来处理这种语言比必须写虚拟功能更好。?
(Mac OS X上的llvm-clang 9.x.x/x64)
用gcc或clang -mavx -fno-implement-inlines
编译AVX翻译单元;如果函数不简单地内联,链接器将必须从SSE翻译单元中找到符号。
来自GCC手册:
-fno-implement-inlines
为了节省空间,请勿发射由#pragma implementation
控制的内联函数的台外副本。如果这会导致链接器错误,如果 这些功能在任何地方都没有被嵌入。
clang也支持此选项。
这确实不是禁用任何内容,它只会禁用发出的函数的独立定义,称为 inline
或类别定义。
启用了优化,一个小的默认构造函数,例如问题中的一个小默认构造函数(并使用当前函数/编译单元的目标ISA选项),使大多数情况下这无关紧要。但是,它将确保未优化的构建在非AVX机器上正常工作。
看来,另一个选项是不使用编译器标志来设置指令集 - 将它们留在默认情况下,而仅包装需要增强指令集的功能:
#include Foo.h
// Switch on AVX optimisations for the function where they're needed
#pragma clang attribute push (__attribute__((target("arch=sandybridge"))), apply_to = function)
void Foo::DoSomething_AVX()
{
// AVX optimised implementation here
}
#pragma clang attribute pop
使用#pragma clang属性push(...),而比简单的 [[]]
或 __attribute__(())
要长一点,似乎具有自动应用于任何模板代码等实例化的属性。范围。
将实现放入一个单独的.cpp文件中,瞧,一切都起作用。另一种方法是使这些函数/方法/构造函数内联。第三种方式(依赖编译器)是将它们设置为"弱参考"属性。
- 初始化具有非默认构造函数的std::数组项的更好方法
- 有没有一种代码密度较低的方法来使用非默认构造函数初始化数组?
- 副本初始化的默认模板参数推导
- 使用 std::分配器在 constexpr 中进行默认初始化
- 在C++中使用默认构造函数初始化对象的不同方法
- 强制使用默认构造函数对成员进行未初始化的声明
- 使用默认构造函数初始化对象的不同方法
- 在没有默认构造函数时使用垃圾数据初始化对象
- 为什么对象默认初始化,但基元不在C++?
- 默认参数和空列表初始化
- 为什么std::atomic的默认构造函数不默认初始化底层存储值
- C++中未初始化成员布尔变量的默认值是多少?
- 两个成员,在Base中默认初始化,可能在Derived中非默认初始化
- 默认初始化无法正常工作
- 如何用默认值0或-1初始化unordered_set
- C++11 默认类成员初始化与初始值设定项列表同时
- 使用聚合初始化模拟默认函数参数是否存在任何陷阱?
- 初始化在类类型 #define 中定义的非静态成员数组,不带默认 ctor
- 在皮条类中初始化默认值的最佳位置
- 值初始化:默认初始化或零初始化