Выровненные типы и передача аргументов по значению - PullRequest
12 голосов
/ 13 декабря 2010

Передача выровненных типов или структур с выровненными типами по значению не работает с некоторыми реализациями. Это нарушает контейнеры STL, потому что некоторые методы (такие как изменение размера) принимают свои аргументы по значению.

Я запускаю некоторые тесты с Visual Studio 2008 и не совсем уверен, когда и как сбой передачи по значению. Моя главная задача - функция foo . Кажется, он работает нормально, но может ли это быть результатом встраивания или какого-то другого совпадения? Что если я поменяю его подпись на void foo (const __m128 &) ?

Ваш вклад очень важен. Спасибо.

struct A
{
    __m128 x;
    int n;
};

void foo(__m128);
void bar(A);

void f1()
{
    // won't compile
    // std::vector<A> vec1(3);

    // compiles, but fails at runtime when elements are accessed
    std::vector<__m128> vec2(3);

    // this seems to work. WHY???
    std::vector<__m128, some_16_byte_aligned_allocator<__m128> > vec3(3);

    __m128 x;
    A a;

    // passed by value, is it OK?
    foo(x);

    // won't compile
    //bar(a);
}

EDIT. STL дает сбой даже с выровненным распределителем, потому что проблема передачи по значению остается.

Нашел эту ссылку передать __m128 по значению

Ответы [ 2 ]

2 голосов
/ 13 декабря 2010

Я думаю, что единственный безопасный способ сделать это в общем случае - перейти по ссылке.Некоторые платформы (например, Xbox 360 ) поддерживают передачу векторных аргументов в регистрах, но я не думаю, что это возможно на x86.

Для случая std::vector вам потребуетсяубедитесь, что выделенная память выровнена до 16 байтов;в противном случае произойдет сбой при попытке выполнить большинство операций с невыровненными векторами.

Если вы поддерживаете несколько платформ, безопасный план - использовать typedef например

typedef const MyVector& MyVectorParameter;

Затем вы можете изменить typedef на платформах, которые поддерживают передачу вектора по значению.

1 голос
/ 13 декабря 2010

часто используемая функция resize () вызывает все выравнивание, и, возможно, вы можете попробовать специализировать векторный шаблон для __m128?

...