我经常使用基于编译器的矢量化,例如,用于AVX.我试图#pragma vector aligned通过依赖C++ 11对齐功能,在不依赖基于编译器的扩展(例如Intel )的情况下提出一种更清晰的方法.如果您考虑下面的代码,例如,aligned::array<double,48> my_array;允许我在堆栈中声明一个具有正确对齐的数组,并且如果它在相同的转换单元中使用,则编译器似乎认识到这一点.
我现在的问题是如何声明具有对齐参数的函数.我最成功的尝试是,例如,aligned::ptr<double>在f()下面的函数中使用.
gcc在没有警告(使用-std=c++0x -O3)的情况下编译它,并且循环被矢量化.icc然而,英特尔发出警告并且没有正确地向量化(warning #3463: alignas does not apply here; using type alignas(64) = T;).
谁是对的?我使用alignas有什么问题吗?有没有更好的方法来实现这一目标?
namespace aligned {
template <class T, int N>
using array alignas(64) = T[N];
template <class T>
using type alignas(64) = T;
template <class T>
using ptr = type<T> *;
}
#ifdef __ICC
#define IVDEP "ivdep"
#else
#define IVDEP "GCC ivdep"
#endif
void f(aligned::ptr<double> x, …Run Code Online (Sandbox Code Playgroud) 我经常需要将动态数组的开头与用于矢量化的16,32或64字节边界对齐,例如,对于SSE,AVX,AVX-512.我正在寻找一种透明和安全的方式,特别是与智能指针一起使用它std::unique_ptr.
比如分配和释放例程的实现
template<class T>
T * allocate_aligned(int alignment, int length)
{
// omitted: check minimum alignment, check error
T * raw = 0;
// using posix_memalign as an example, could be made platform dependent...
int error = posix_memalign((void **)&raw, alignment, sizeof(T)*length);
return raw;
}
template<class T>
struct DeleteAligned
{
void operator()(T * data) const
{
free(data);
}
};
Run Code Online (Sandbox Code Playgroud)
我想做这样的事情
std::unique_ptr<float[]> data(allocate_aligned<float>(alignment, length));
Run Code Online (Sandbox Code Playgroud)
但我无法弄清楚如何unique_ptr使用正确Deleter而无需用户指定它(这是导致错误的潜在原因).我找到的替代方法是使用模板别名
template<class T>
using aligned_unique_ptr = std::unique_ptr<T[], DeleteAligned<T>>;
Run Code Online (Sandbox Code Playgroud)
然后我们可以使用
aligned_unique_ptr<float> data(allocate_aligned<float>(alignment, length)); …Run Code Online (Sandbox Code Playgroud) 具有非虚拟析构函数的类如果它们被用作基类(如果使用指向基类的指针或引用来引用子类的实例),则它们是错误的来源.
随着C++ 11添加一个final类,我想知道是否有意义设置以下规则:
每个类必须满足以下两个属性之一:
final(如果它还没有被继承)可能有些情况下这两个选项都没有意义,但我想它们可以被视为应该仔细记录的例外情况.