Самый простой способ - std::aligned_storage
, который принимает выравнивание как второй параметр.
Если у вас его еще нет, вы можете проверить версию Boost .
Тогда вы можете построить свой союз:
union vector {
__m128 simd;
std::aligned_storage<16, 16> alignment_only;
}
Наконец, если это не работает, вы всегда можете создать свой собственный маленький класс:
template <typename Type, intptr_t Align> // Align must be a power of 2
class RawStorage
{
public:
Type* operator->() {
return reinterpret_cast<Type const*>(aligned());
}
Type const* operator->() const {
return reinterpret_cast<Type const*>(aligned());
}
Type& operator*() { return *(operator->()); }
Type const& operator*() const { return *(operator->()); }
private:
unsigned char* aligned() {
if (data & ~(Align-1) == data) { return data; }
return (data + Align) & ~(Align-1);
}
unsigned char data[sizeof(Type) + Align - 1];
};
Он выделит немного больше памяти, чем необходимо, но при этом выравнивание гарантировано.
int main(int argc, char* argv[])
{
RawStorage<__m128, 16> simd;
*simd = /* ... */;
return 0;
}
Если повезет, компилятор сможет оптимизировать работу выравнивания указателя, если обнаружит, что выравнивание необходимо, верно.