我使用__m256
作为模板类的参数(请参阅下面的代码)。在Ubuntu 16.10(Yakkety Yak)上使用g ++ 6.2进行编译时,它会警告我在模板参数上忽略了属性:
警告:忽略模板参数'__m256 {aka __vector(8)float}上的属性'[-Wignored-attributes] typedef vec_array< __ m256> vec256
__m256
类型似乎有一些关于对齐的属性(可能还有其他一些?)。下面显示的这个原始容器类的唯一目的(生成警告)是为了处理这些特殊Intel变量(__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);
}
答案 0 :(得分:1)
我遇到了同样的警告,但是在一些OpenCL代码中并最终在这里,而没有先查看代码。你可以看到有些人试图在 Making std::vector allocate aligned memory 中试图避免这种警告,但在我看来,它并不值得。
简短的回答是,除了仅支持128位AVX指令的CPU之外,您不必担心这一点。如果警告严重,那么CPU将在未对齐访问时生成异常。
出现此警告是因为类型__m256
可能是使用大约16个字节的对齐说明符声明的。也就是说,CPU期望向量的每个元素的对齐为16个字节。但是,矢量模板不支持对齐属性。
我认为你必须做一些愚蠢的事情,比如
struct stupidStruct __attribute__(packed) {
unsigned short padding;
std::vector<__m256> vect;
};
强制编译器生成会导致错误的代码。
答案 1 :(得分:1)
可以通过将__m256
之类的向量类型包装为以下结构来消除这些警告:
struct __m256_wrapper {
typedef __m256 VecT;
};
,并在需要时将此结构用作模板参数。因此,您提供的代码将进行如下更改:
///////////////////////////////////////////////////////////////////////////////
// System includes:
#include <x86intrin.h>
#include <cstdint>
static const size_t AVX_alignment = 32;
struct __m256_wrapper {
typedef __m256 VecT;
};
template<typename W>
class vec_array
{
protected:
typename W::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 W>
vec_array<W>::vec_array() : m_pdata(nullptr), m_num_vector_elements(0)
{}
template<typename W>
vec_array<W>::vec_array(size_t num_vector_elements) : m_pdata(nullptr),
m_num_vector_elements(num_vector_elements)
{
allocate(num_vector_elements);
}
template<typename W>
vec_array<W>::~vec_array()
{
free();
}
template<typename W>
void vec_array<W>::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<typename W::VecT*>(_mm_malloc(m_num_vector_elements*sizeof(typename W::VecT), AVX_alignment));
}
template<typename W>
void vec_array<W>::free()
{
if(m_pdata != nullptr)
_mm_free(m_pdata);
}
typedef vec_array<__m256_wrapper> vec256;
int main()
{
vec256 test_vec(10);
}