2015-07-02 2 views
1

Что такое флаг, чтобы включить неравномерный доступ к памяти для ARM NEON в компиляторе LLVM. Я тестировал свою встроенную программу ARM NEON в Xcode. Я доступ к данным из выровненной памяти:Как включить UnAligned Access для ARM NEON в компиляторе LLVM?

char TempMemory[32] = {0}; 
char * pTempMem = TempMemory; 
pTempMem += 7; 
int32x2_t i32x2_value = vld1_lane_s32((int32_t const *) pTempMem, i32x2_offset, 0); 

Эквивалента сборки для внутреннего должна быть VLD1.32 {d0[0]}, [pTempMem], но компилятор выравнивать его к следующим кратному 32 и доступ к данным. Из-за этого моя программа не работает нормально.

Итак, как я могу включить неровный доступ в компиляторе LLVM?

+0

Я бы понял, если компилятор выпустил инструкции с подсказками выравнивания, и программа просто взяла ошибку выравнивания во время выполнения, но компилятор, фактически генерирующий код для доступа к другому адресу, чем тот, который указан, звучит очень странно. Можете ли вы добавить код (и, возможно, соответствующую разборку) к вопросу, чтобы сделать более понятным, что на самом деле происходит здесь? – Notlikethat

+0

@Notlikethat Мой код: «char TempMemory [32] = {0}; \t \t char * pTempMem = TempMemory; pTempMem + = 7; \t int32x2_t i32x2_value = vld1_lane_s32 ((int32_t const *) pTempMem, i32x2_offset, 0); ' Эквивалент узел для внутренней должен быть VLD1.32 {d0 [0]}, [pTempMem] Но компилятором сборка VLD1.32 {d0 [0]}, [pTempMem: 32] – srat

+0

Пожалуйста [ отредактируйте сам вопрос] (http://stackoverflow.com/posts/31176671/edit), а не размещайте важные комментарии в комментариях. Особенно в случае кода. – Notlikethat

ответ

1

Это на самом деле не проблема NEON, это проблема, C, и вопрос:

vld1_lane_s32((int32_t const *) pTempMem , i32x2_offset, 0); 

Кастинг указатель является сообщение компилятора говоря: «Эй, я знаю, это выглядит плохо, но поверь мне, я действительно знаю, что я делаю ». Преобразование указателя типа A в указатель на тип B, если указатель не имеет подходящего выравнивания для типа B, дает неопределенное поведение. Поэтому компилятор может предположить, что аргумент vld_1_lane_s32 всегда выровнен по 32 битам, потому что нет никакого действительного способа, которым это не могло быть (и вы пообещали, что знаете, что делаете), поэтому он испускает инструкцию с помощью подсказка выравнивания.

Теперь вы можете играть с вариантами, пытаясь получить различное неопределенное поведение, соответствующее тому, что вы хотите, но это просто связано с проблемой, а не фиксирует ее. То, что базовый набор инструкций NEON может поддерживать несвязанные обращения, не влияет на определение языка C и ограничений по выравниванию данных.

Я не знаком с тем, как умный LLVM, поэтому я не уверен, если просто опуская указатель бросание будет работать (технически, позволяет C превращающего char * к любому другому типу указателя данных, так что должны быть способный самостоятельно сортировать выравнивание). В противном случае решение должно использовать соответствующую операцию vld*_u8 для загрузки данных в вектор по правильному типу, а затем передать это с помощью vreinterpret_s32_u8 после того, как оно находится в регистре.

+0

Чтобы узнать, когда компилятор предполагает более высокие требования к выравниванию при трансляции, используйте флаг предупреждения '-Wcast-align'. См. [Параметры предупреждения GCC] (https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html). –

Смежные вопросы