Следствие предупреждения GCC: игнорирование атрибутов в аргументе шаблона (-Wignored-attribute)

Я использую __m256 в качестве аргумента для класса шаблона (см. Код ниже). При компиляции с g++ версии 6.2 в Ubuntu 16.10 (Yakkety Yak) он предупреждает меня об атрибутах, игнорируемых в аргументе шаблона:

предупреждение: игнорирование атрибутов в аргументе шаблона '__m256 {aka __vector (8) float} [-Wignored-attribute] typedef vec_array <__ m256> vec256

Тип __m256 кажется, имеет некоторые атрибуты, касающиеся выравнивания (и, возможно, некоторые другие?). Единственная цель этого примитивного класса контейнеров, показанного ниже (и генерирующего предупреждение), состоит в обработке выравнивания памяти в куче для этих специальных переменных Intel (__m256, __m128 и т.д.).

Когда я использую этот контейнерный класс в моей общей программе, он, кажется, работает нормально. Однако мой вопрос заключается в том, каковы последствия, когда GCC игнорирует эти атрибуты (я уже читал, что руководство GCC должно сказать по этому вопросу).

  1. Есть ли хороший способ избавиться от этих предупреждений?
  2. Должен ли я беспокоиться об этом?
  3. Что может быть худшего, если я проигнорирую это предупреждение?

Для справки, код ниже выдает это предупреждение.

///////////////////////////////////////////////////////////////////////////////
// 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);
}

Ответ 1

Я столкнулся с тем же предупреждением, но в каком-то коде OpenCL, и в итоге оказался здесь, не глядя сначала на код. Вы можете увидеть, как некоторые люди пытаются избежать этого предупреждения, когда заставляют std :: vector выделять выровненную память, но, на мой взгляд, оно того не стоит.

Короткий ответ: вам не нужно об этом беспокоиться, за исключением процессоров, которые поддерживают только 128-битные инструкции AVX. Если бы предупреждение было серьезным, то ЦП сгенерировал бы исключение при неприсоединенном доступе.

Причина появления этого предупреждения заключается в том, что тип __m256, вероятно, объявлен со спецификатором выравнивания, вероятно, 16 байтов. То есть процессор будет ожидать, что выравнивание каждого из элементов вектора будет 16 байтов. Тем не менее, шаблон для вектора не учитывает атрибут выравнивания.

Я думаю, что вы должны сделать что-то глупое, как

struct stupidStruct __attribute__(packed) {
    unsigned short padding;
    std::vector<__m256> vect;
};

заставить компилятор генерировать код, который может вызвать ошибку.