Успешная компиляция инструкции SSE с помощью qmake (но SSE2 не распознается)

Я пытаюсь скомпилировать и запустить свой код, перенесенный из Unix в Windows. Мой код чистый C++ и не использует классы Qt. это нормально в Unix.

Я также использую Qt Creator в качестве IDE и qmake.exe с -spec win32-g++ для компиляции. Поскольку в моем коде есть инструкции sse, я должен включить заголовок emmintrin.h.

Я добавил:

QMAKE_FLAGS_RELEASE += -O3 -msse4.1 -mssse3 -msse3 -msse2 -msse

QMAKE_CXXFLAGS_RELEASE += -O3 -msse4.1 -mssse3 -msse3 -msse2 -msse

В файле .pro. Мне удалось скомпилировать мой код без ошибок. но после запуска он выдает ошибку времени выполнения при выполнении некоторых функций, содержащих __m128 или что-то подобное.

Когда я открываю emmintrin.h, я вижу:

#ifndef __SSE2__
# error "SSE2 instruction set not enabled"
#else

и не определено после #else.

Я не знаю, как включить SSE на моем компьютере.

Платформа: Windows Vista

Тип системы: 64-битная

Процессор: Intel(R) Core(TM) i5-2430M с частотой 2,40 Гц

Кто-нибудь знает решение?

Заранее спасибо.


person Hamid Bazargani    schedule 06.09.2013    source источник
comment
Можно поподробнее об ошибках во время выполнения? Пожалуйста, скопируйте и вставьте фактические сообщения об ошибках.   -  person Paul R    schedule 06.09.2013
comment
Это не проблема ошибки времени выполнения. однако нарушение доступа. Основная проблема в том, что __SSE__ не определен. Я уверен в остальной части кода.   -  person Hamid Bazargani    schedule 06.09.2013
comment
Что заставляет вас думать, что __SSE__ не определено? Вы, кажется, сбиты с толку тем, что увидели в заголовке, что здесь не актуально.   -  person Paul R    schedule 06.09.2013
comment
Да, кажется, я запутался. Потому что я вижу серые линии в создателе Qt, что означает, что эти строки не будут скомпилированы. кроме того, IDE говорит, что __m128 не является именем типа. Но при пошаговом запуске кода в режиме отладки. Часть кода SSE идет хорошо. Думаю проблема где-то в другом. Вылетает при выполнении функции _mm_load_ps(). Возможно, из-за плохого распределения ввода. Кстати, мне интересно, поддерживается ли эта функция на моей машине или ....?   -  person Hamid Bazargani    schedule 06.09.2013
comment
Вот почему я попросил вас опубликовать фактическое сообщение об ошибке во время выполнения - это звучит как типичная проблема с несогласованными данными SSE. Попробуйте правильно выровнять данные или используйте _mm_loadu_ps вместо _mm_load_ps.   -  person Paul R    schedule 06.09.2013
comment
Спасибо. изменение на _mm_loadu_ps решило это. Но как я могу выровнять свои данные. мои данные представляют собой структуру из двух переменных с плавающей запятой. и я определил MYSTRUCT *data. Вход функции _mm_loadu_ps((float*) data). В любом случае ваш ответ решил мой вопрос.   -  person Hamid Bazargani    schedule 06.09.2013
comment
В Windows/Visual Studio вы можете использовать атрибут declspec(align(16)) для статических выделений или _aligned_malloc для динамических выделений. Для gcc и большинства других цивилизованных платформ/компиляторов используйте __attribute__ ((align(16))) для первого и posix_memalign для второго.   -  person Paul R    schedule 06.09.2013
comment
P.S. поскольку это, похоже, решило вашу проблему, я преобразовал приведенные выше комментарии в ответ (см. Ниже).   -  person Paul R    schedule 06.09.2013


Ответы (1)


Похоже, ваши данные не выровнены по 16 байтам, что является требованием для загрузок SSE, таких как mm_load_ps. Вы также можете:

  • используйте _mm_loadu_ps как временное решение. На более новых процессорах падение производительности из-за несогласованных нагрузок, таких как это, довольно мало (на старых процессорах это гораздо более существенно), но его все же следует избегать, если это возможно.

or

  • исправить выравнивание памяти. В Windows/Visual Studio вы можете использовать атрибут declspec(align(16)) для статических выделений или _aligned_malloc для динамических выделений. Для gcc и большинства других цивилизованных платформ/компиляторов используйте __attribute__ ((align(16))) для первого и posix_memalign для второго.
person Paul R    schedule 06.09.2013
comment
Я не согласен с тем, что снижение производительности при несогласованных нагрузках довольно мало. В последний раз, когда я проверял свой i7-2600K (Sandy Bridge), он был немалым — эффективность моего кода GEMM значительно падала из-за неправильно выровненных данных. Что невелико, так это разница в производительности loadu и load при выравнивании данных, чего раньше не было (т.е. load больше не нужен). Однако loadu для несовмещенных данных по-прежнему намного медленнее. - person Z boson; 07.09.2013
comment
Я написал программу для Windows, чтобы измерить штраф _mm_loadu_ps. Программа загружает числа с плавающей запятой из массива с помощью _mm_loadu_ps или _mm_load_ps и отображает время выполнения для каждого из них. Цикл тестирования также содержит инструкцию добавления, чтобы оптимизаторы не снимали нагрузку. Сборка с помощью mingw64/gcc 4.8 или Visual Studio дает тот же результат для SB (@4,0 ГГц): 0,75 нс на цикл для _mm_load_ps и 0,78 нс на цикл для _mm_loadu_ps. Так что, если я правильно закодировал тест, Sandy Bridge проделает впечатляющую работу по снижению невыровненной нагрузки. Исходный код находится здесь: notabs.org/misc/alignment.7z. - person ; 07.09.2013
comment
@ScottD, спасибо за код! Я мельком посмотрел. Выглядит неплохо. Я заметил одну вещь: вы тестируете только регион L1. Я должен буду изучить это снова. - person Z boson; 07.09.2013
comment
@ScottD, поэтому я запустил ваш код на своем процессоре i5-3317U с частотой 1,70 ГГц под Linux (после некоторых модификаций) и получил 1,22 нс для невыровненного и 1,17 для выровненного. Это примерно на 4% медленнее. Основываясь на этом утверждении Пола, падение производительности при несогласованных нагрузках, таких как эта, довольно мало (на старых процессорах это гораздо более существенно), но его все же следует избегать, если это возможно. точно. Я должен проверить это более тщательно. - person Z boson; 07.09.2013
comment
@redrum: бывают случаи, когда несогласованные нагрузки могут иметь косвенное влияние на производительность, в основном там, где размер кэша L1 имеет решающее значение. Невыровненные загрузки, когда вектор разделен между строками кэша, могут привести к загрузке дополнительных строк кэша, поэтому использование кэша может стать менее эффективным, поскольку вытесняется больше строк кэша, чем это строго необходимо. То же самое относится и к записям TLB, страницам DRAM и т. д., но они, вероятно, с меньшей вероятностью будут фактором для выровненных и несовмещенных загрузок. - person Paul R; 07.09.2013
comment
@redrum, больно портировать этот код, который я знаю. Я попробовал несколько больших размеров массива, и результаты были такими же, пока общий размер буфера не превысил размер кэша L3 в 8 МБ. После этого _mm_loadu_ps и _mm_load_ps одинаково замедлились. Процессор AMD A6-3650 также хорошо справляется с невыровненными данными. Но даже в этом случае выравнивание данных выгодно и является небольшой платой за повышенную мобильность и удобство работы со старыми процессорами. Как объяснил Пол Р., ценное пространство кэша L1 тратится впустую, когда массив не выровнен, и это может повлиять на производительность для определенных циклов. - person ; 07.09.2013
comment
@PaulR, спасибо за информацию. Возможно, это то, что я видел в прошлом (когда впервые начал писать свой код GEMM). Кажется, я припоминаю гораздо худшую производительность при невыровненных нагрузках, и с тех пор я не удосужился протестировать неравномерную память. Если мне удастся воспроизвести/восстановить тесты, которые я сделал, я отправлю ТАК вопрос о них. - person Z boson; 07.09.2013
comment
@ScottD, сделать код кроссплатформенным/компилятором довольно просто. Используйте _mm_malloc вместо _aligned_malloc (это был мой вопрос в предыдущая жизнь SO), а также omp_get_wtime() (вместо таймера производительности Windows), и ваш код будет работать на GCC, MinGW, MSVC и ICC с Linux и Windows (и, возможно, OSX). Единственная часть, которую я не реализовал, — это изменение приоритета задачи. У меня нет хорошего решения для этого, поэтому я прокомментировал его. - person Z boson; 07.09.2013