2016-07-29 14 views
2

Я пытаюсь проверить некоторые из Intel Intrinsics, чтобы увидеть, как они работают. Таким образом, я создал функцию, чтобы сделать это для меня, и это код:Проблема с __m256 типа intel intrinsics

void test_intel_256() 
{ 
__m256 res,vec1,vec2; 

__M256_MM_SET_PS(vec1, 7.0, 7.0, 7.0, 7.0, 7.0, 7.0, 7.0, 7.0); 
__M256_MM_SET_PS(vec1, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0); 

__M256_MM_ADD_PS(res,vec1,vec2); 

if (res[0] ==9 && res[1] ==9 && res[2] ==9 && res[3] ==9 
    && res[4] ==9 && res[5] ==9 && res[6] ==9 && res[7] ==9) 
    printf("Addition : OK!\n"); 
else 
    printf("Addition : FAILED!\n"); 
} 

Но тогда я получаю эти ошибки:

error: unknown type name ‘__m256’ 
error: subscripted value is neither array nor pointer nor vector 
error: subscripted value is neither array nor pointer nor vector 
error: subscripted value is neither array nor pointer nor vector 
error: subscripted value is neither array nor pointer nor vector 
error: subscripted value is neither array nor pointer nor vector 
error: subscripted value is neither array nor pointer nor vector 
error: subscripted value is neither array nor pointer nor vector 
error: subscripted value is neither array nor pointer nor vector 
error: subscripted value is neither array nor pointer nor vector 

Это означает, что компилятор не распознает тип __m256 и вследствие этого он не может видеть res как массив поплавков. Я включаю эти библиотеки mmintrin.h, emmintrin.h, xmmintrin.h и я использую затмение Марс

Так что я хочу знать, является ли проблема с компилятором или аппаратное обеспечение или что-то еще? и как я могу его решить? Спасибо!

+0

Вы уверены, что ваш процессор поддерживает AVX? Какой процессор вы используете? –

+0

@ DanielMargosian: Даже если их процессор не поддерживает AVX, компилятор все равно должен его скомпилировать. (Cross сборник есть). – zindorsky

+0

Мой процессор ** Intel® Core ™ i7-4700MQ CPU @ 2.40GHz × 8 ** и поддерживает ** SSE4.1/4.2, AVX 2.0 ** –

ответ

3

MMX и SSE2 являются базовыми для x86-64, но AVX - нет. Вам do необходимо специально включить AVX, где вы не использовали SSE2.

Постройте с помощью -march=haswell или любого другого процессора, который у вас есть на самом деле. Или просто используйте -mavx.

берегись, gcc -mavx с по умолчанию tune=generic разделится 256b loadu/storeu в vmovups xmm встроенные функции/vinsertf128, что плохо, если ваши данные фактически выровнены большую часть времени, и особенно плохо на Haswell с ограниченной пропускной способностью перетасовка-порта.

Это хорошо для семейства Sandybridge и Bulldozer, если ваши данные действительно не выровнены. См. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80568: он даже влияет на векторный целочисленный код AVX2, хотя все эти настройки испытывают все процессоры AVX2 (за исключением, может быть, экскаватора и Ryzen). tune=generic не учитывает, какое расширение набора инструкций включено, и нет tune=generic-avx2.

Вы можете использовать -mavx2 -mno-avx256-split-unaligned-load -mno-avx256-split-unaligned-store. Это все еще не позволяет использовать другие параметры настройки (например, оптимизацию для макро-слияния сравнения и ветвления), которые имеют все современные процессоры x86 (кроме маломощных), но это не поддерживается gcc tune = generic. (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78855).


также:

Я включаю эти библиотеки mmintrin.h, emmintrin.h, xmmintrin.h

Не делай этого. Always just include immintrin.h in SIMD code. Он извлекает все расширения SSE/AVX от Intel. Вот почему вы получите error: unknown type name ‘__m256’


Имейте в виду, что индексацию векторные типы лежат __m256 нестандартно и непереносимой. Они не массивы, и нет причин вам должен ожидать [] работать как массив. Извлечение третьего элемента или что-то из SIMD-вектора в регистр требует инструкции перетасовки, а не нагрузки.


Если вы хотите удобные оберток для векторных типов, которые позволяют делать такие вещи, как использование operator[] для извлечения скаляров из элементов вектора переменных, взгляните на Agner Тумана-х Vector Class Library. Это GPLed, поэтому вам придется искать другие библиотеки-обертки, если это проблема.

Это позволяет делать такие вещи, как

// example from the manual for operator[] 
Vec4i a(10,11,12,13); 
int b = a[2]; // b = 12 

Вы можете использовать обычные встроенные функции по типам VCL. Vec8f - прозрачная обертка на __m256, поэтому вы можете использовать ее с _mm256_mul_ps.

1

попробовать это

разреш = _MM_ADD_PS (vec1, vec2); , поскольку прототипом __M256_MM_ADD_PS является

__m256 _MM_ADD_PS (__ m256, __ m256);

требуется два __m256 типов данных в качестве параметров и возвращает их сумму в качестве __m256 данных, так же, как

Int оных (междунар, Int);

для инициализации

VEC = _MM_setr_PS (7.0,7.0,7.0,7.0,7.0,7.0,7.0,7.0) или

VEC = _MM_LOAD_PS (ARR) & или

VEC = _MM_LOAD_PS (ptr)

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

  • Нет связанных вопросов^_^