我__m256用作模板类的参数(参见下面的代码).在Ubuntu 16.10(Yakkety Yak)上使用g ++ 6.2进行编译时,它会警告我在模板参数上忽略了属性:
警告:忽略模板参数'__m256上的属性{aka __vector(8)float}'[-Wignored-attributes] typedef vec_array <__ m256> vec256
这种__m256类型似乎有一些关于对齐的属性(也许还有其他一些?).(其产生警告和)下面示出该原语容器类的唯一目的是处理在堆上这些特殊英特尔变量(存储器对准__m256,__m128等等).
当我在整个程序中使用此容器类时,它似乎工作正常.但是,我的问题是当GCC忽略这些属性时会产生什么影响(我已经阅读了GCC手册对该问题的看法).
作为参考,下面的代码会产生此警告.
///////////////////////////////////////////////////////////////////////////////
// System includes:
#include <x86intrin.h>
#include <cstdint>
static const size_t AVX_alignment = 32;
template<typename VecT>
class vec_array
{
protected:
VecT* m_pdata;
size_t m_num_vector_elements;
public:
vec_array();
vec_array(size_t num_vector_elements);
virtual ~vec_array();
void allocate(size_t num_vector_elements);
void free();
};
template<typename VecT>
vec_array<VecT>::vec_array() : m_pdata(nullptr), m_num_vector_elements(0)
{}
template<typename VecT>
vec_array<VecT>::vec_array(size_t num_vector_elements) : m_pdata(nullptr),
m_num_vector_elements(num_vector_elements)
{
allocate(num_vector_elements);
}
template<typename VecT>
vec_array<VecT>::~vec_array()
{
free();
}
template<typename VecT>
void vec_array<VecT>::allocate(size_t num_vector_elements)
{
if( m_num_vector_elements == num_vector_elements)
return;
m_num_vector_elements = num_vector_elements;
free();
m_pdata = reinterpret_cast<VecT*>(_mm_malloc(m_num_vector_elements*sizeof(VecT), AVX_alignment));
}
template<typename VecT>
void vec_array<VecT>::free()
{
if(m_pdata != nullptr)
_mm_free(m_pdata);
}
typedef vec_array<__m256> vec256;
int main()
{
vec256 test_vec(10);
}
Run Code Online (Sandbox Code Playgroud)
小智 5
我在一些OpenCL代码中遇到了同样的警告,最终没有先查看代码,就到了这里。您可以在Making std::vector allocatealigned memory中看到有些人如何尝试避免此警告,但在我看来,这是不值得的。
简而言之,除了仅支持 128 位 AVX 指令的 CPU 之外,您不必担心这一点。如果警告严重,则 CPU 会针对未对齐访问生成异常。
出现此警告的原因是因为该类型__m256可能是使用大约 16 字节的对齐说明符声明的。也就是说,CPU 期望向量的每个元素的对齐方式为 16 字节。但是,矢量模板不支持对齐属性。
我认为你必须做一些愚蠢的事情,比如
struct stupidStruct __attribute__(packed) {
unsigned short padding;
std::vector<__m256> vect;
};
Run Code Online (Sandbox Code Playgroud)
强制编译器生成会导致错误的代码。