2015-01-06 2 views
1

У меня очень большая библиотека, и я хочу скомпилировать ее с поддержкой AVX2 (но мой процессор поддерживает полностью AVX). Эта библиотека также имеет внутреннюю проверку выполнения, независимо от того, поддерживает ли процессор AVX2 или нет. Что-то вроде этого:Компиляция с поддержкой и запуском AVX2

#if __AVX2__ 
if (support_avx2) 
{ 
    // vectorized code 
} 
#endif 
// simple C++ code 

мне удалось собрать библиотеку с поддержкой AVX2, но когда я запускаю тесты у меня в самом начале:

Illegal instruction: 4 

Любые идеи? Цель состоит в том, чтобы собрать библиотеку со всеми доступными оптимизациями и функциями и проверить их во время выполнения.

p.s. Я работаю над OSX

+1

Вы код не проверяет, если ваш процессор поддерживает AVX2. Он проверяет, были ли установлены параметры вашего компилятора для AVX2. Вам нужен диспетчер процессора. Вот несколько ссылок на [warn-gcc-from-automatic-use-avx-and-fma-instructions-when-compiled-w] (https://stackoverflow.com/questions/18868235/preventing-gcc-from- автоматически, используя-AVX-и-FMA-инструкции, когда скомпилированные-W/25911959 # 25911959). –

+0

Фактически, support_avx2 является логическим флагом, который отражает соответствующий бит cpuid. – sandye51

+0

Когда вы компилируете для AVX2, ваш компилятор предполагает, что он может использовать AVX2 всякий раз, когда захочет (например, для векторизации). Вы должны скомпилировать для самого низкого общего знаменателя (я думаю, AVX в вашем случае), который вы хотите поддержать диспетчера. Затем скомпилируйте отдельные объектные файлы для каждого AVX и AVX2, а затем попросите диспетчера перейти к соответствующей версии. –

ответ

2

Нет простого способа запуска кода AVX2 на CPU, который имеет только AVX (например, Sandy Bridge/Ivy Bridge). Вы можете использовать Intel's SDE для запуска кода для целей тестирования (это действительно работает очень хорошо, по крайней мере, для исполняемых файлов командной строки), но может быть проще получить Haswell Mac для разработки и тестирования.

+0

Является ли SDE Intel простой в установке и использовании? Я рассматривал это для AVX512. –

+2

Да, я нашел его легким в установке (по крайней мере на OS X - Linux не должен быть проблемой, я думаю), и он работает хорошо - только неподдерживаемые инструкции эмулируются, а все остальное работает на полной скорости, поэтому он не страдает от обычная проблема с эмуляторами процессора, где вы обнаружите, что работаете на нескольких порядках медленнее, чем на реальном процессоре. –

+0

@PaulR, учитывая DLL/Dylib/O, есть ли способ узнать, какие команды требуется для этого? Спасибо. – Royi

1

В принципе, вы можете использовать cpuid, чтобы проверить, поддерживает ли процессор функцию, которую вы хотите использовать, а затем переходите к ее использованию, если это так.

#if __AVX2__ 

относится только к машине, на которой вы компилируете и обычно устанавливается флагами компилятора.

+0

На самом деле, support_avx2 является логическим флагом, который отражает соответствующий бит cpuid. – sandye51

+0

Ну, вероятно, это не работает так, как вы думаете, если вы получаете незаконную инструкцию, как вы говорите. Я бы рекомендовал запустить его под gdb, а затем разобрать, чтобы вы могли видеть точную незаконную инструкцию и откуда она пришла, затем отступать оттуда, чтобы найти вашу ошибку. – Hal

1

Если вы только компилируете для AVX2, ваш компилятор предполагает, что он может использовать AVX2, когда захочет. Вы должны скомпилировать для самого низкого общего оборудования, которое хотите использовать, а затем проверить, какое оборудование доступно, а затем настроить функции на соответствующие функции из объектных файлов, скомпилированных с этим оборудованием. Это CPU dispatcher. Вот ленивый человек диспетчер:

//foo.cpp 
#if __AVX2__ 
void foo_AVX2() { 
    //AVX2 code 
    //make sure to call zeroupper!!! 
} 
#else 
void foo_AVX2(); 
void foo() { 
    //simple C++ code 
} 

int main(void) { 
    bool support_avx2 = detect_AVX2(); 
    if (support_avx2) { 
     foo_AVX2(); 
    } 
    else { 
     foo(); 
    } 
} 
#endif 

Затем компилировать так:

g++ -c -O3 -mavx2 foo.cpp -o foo_AVX2.o 
g++ -O3 foo.cpp foo_AVX2.o 
Смежные вопросы