Как предлагается в комментариях, вы можете выполнить поиск во всех файлах ELF вашей системы и разобрать их, чтобы проверить, используют ли они инструкции AVX-512:
$ objdump -d /lib64/ld-linux-x86-64.so.2 | grep %zmm0
14922: 62 f1 fd 48 7f 44 24 vmovdqa64 %zmm0,0xc0(%rsp)
14a2d: 62 f1 fd 48 6f 44 24 vmovdqa64 0xc0(%rsp),%zmm0
14c2c: 62 f1 fd 48 7f 81 50 vmovdqa64 %zmm0,0x50(%rcx)
14ca0: 62 f1 fd 48 6f 84 24 vmovdqa64 0x50(%rsp),%zmm0
(Кстати, libc и ld.so действительно включают инструкции AVX-512, это не те, которые вы ищете?)
Однако вы можете найти двоичный файл, который вы даже не выполняете, и пропустите динамически несжатый код и т. Д.
Если у вас есть сомнения по поводу процесса (потому что perf
сообщают CORE_POWER.LVL*_TURBO_LICENSE
события), я предлагаю сгенерировать дамп ядра этого процесса и разобрать его (обратите внимание, что первая строка позволяет также дампить код):
$ echo 0xFF > /proc/<PID>/coredump_filter
$ gdb --pid=<PID>
[...]
(gdb) gcore
Saved corefile core.19602
(gdb) quit
Detaching from program: ..., process ...
$ objdump -d core.19602 | grep %zmm0
7f73db8187cb: 62 f1 7c 48 10 06 vmovups (%rsi),%zmm0
7f73db818802: 62 f1 7c 48 11 07 vmovups %zmm0,(%rdi)
7f73db81883f: 62 f1 7c 48 10 06 vmovups (%rsi),%zmm0
[...]
Затем вы можете легко написать небольшой скрипт на Python, чтобы добавить точку останова (или точку трассировки) для каждой инструкции AVX-512. Что-то вроде
(gdb) python
>import os
>with os.popen('objdump -d core.19602 | grep %zmm0 | cut -f1 -d:') as pipe:
> for line in pipe:
> gdb.Breakpoint("*" + line)
Конечно, это создаст несколько сотен (или тысяч) точек останова. Однако накладные расходы на точку останова достаточно малы, чтобы GDB мог это поддерживать (я думаю, <1 КБ для каждой точки останова).
Еще один способ - запустить ваш код на виртуальной машине. Особенно рекомендую libvex. libvex используется для динамического инструментария кода (утечка памяти, профилирование памяти и т. д.). libvex интерпретирует машинный код, переводит его в промежуточное представление и перекодирует машинный код для выполнения ЦП. Самый известный проект, использующий libvex, - это valgrind (честно говоря, libvex является серверной частью valgrind).
Следовательно, вы можете запускать свое приложение с libvex без каких-либо инструментов с помощью:
$ valgrind --tool=none YOUR_APP
Теперь вам нужно написать инструмент для libvex, чтобы обнаруживать использование AVX-512. Однако libVEX (пока) НЕ поддерживает AVX-512. Итак, как только ему нужно выполнить инструкцию AVX-512, он выйдет из строя с недопустимой инструкцией.
$ valgrind --tool=none YOUR_APP
[...]
vex amd64->IR: unhandled instruction bytes: 0x62 0xF1 0xFD 0x48 0x28 0x84 0x24 0x8 0x1 0x0
vex amd64->IR: REX=0 REX.W=0 REX.R=0 REX.X=0 REX.B=0
vex amd64->IR: VEX=0 VEX.L=0 VEX.nVVVV=0x0 ESC=NONE
vex amd64->IR: PFX.66=0 PFX.F2=0 PFX.F3=0
==20061== valgrind: Unrecognised instruction at address 0x10913e.
==20061== at 0x10913E: main (in ...)
==20061== Your program just tried to execute an instruction that Valgrind
==20061== did not recognise. There are two possible reasons for this.
==20061== 1. Your program has a bug and erroneously jumped to a non-code
==20061== location. If you are running Memcheck and you just saw a
==20061== warning about a bad jump, it's probably your program's fault.
==20061== 2. The instruction is legitimate but Valgrind doesn't handle it,
==20061== i.e. it's Valgrind's fault. If you think this is the case or
==20061== you are not sure, please let us know and we'll try to fix it.
==20061== Either way, Valgrind will now raise a SIGILL signal which will
==20061== probably kill your program.
==20061==
==20061== Process terminating with default action of signal 4 (SIGILL)
==20061== Illegal opcode at address 0x10913E
==20061== at 0x10913E: main (in ...)
==20061==
Примечание: этот ответ был протестирован с помощью:
#include <immintrin.h>
int main(int argc, char *argv[]) {
__m512d a, b, c;
_mm512_fnmadd_pd(a, b, c);
}
person
Jérôme Pouiller
schedule
12.09.2018
-mno-avx512f
должен автоматически отключать avx512cd / pf / er / etc, верно? Вы пробовали использоватьobjdump -d
grep для своего исполняемого файла и его библиотечных зависимостей? - person that other guy   schedule 24.08.2018ldd <your prog>
должен вернуть список имен библиотек. Имена должны быть в порядке, но пути могут быть отключены в зависимости от вашей среды. - person jww   schedule 24.08.2018-mno-avx512f
отключает только AVX-512 в коде, который я компилирую, и, похоже, он работает (нет AVX-512 в сгенерированном коде). Однако библиотеки, статически или динамически связанные, могут иметь AVX-512. Проблема с grepping заключается в том, что он дает только статическое представление о том, что там находится, а не о том, где / почему путь фактически выполняется. Например, было бы нормально иметьmemcpy
где-нибудь, где используется AVX-512, но не ожидать, что ваша программа действительно вызовет его. - person BeeOnRope   schedule 24.08.2018memcpy
. Легкий код AVX-512 должен работать на частотах AVX2. - person wim   schedule 25.08.2018-static
на Ubuntu 16.04. Действительно,objdump
показал регистры zmm и код AVX-512 (vmov
-s), хотя 16.04 довольно старый. - person wim   schedule 25.08.2018vzeroupper
s в каждую функцию, имеющую какой-либо AVX. Кроме того, большая часть кода в любом случае будет работать на скорости AVX512. - person Mysticial   schedule 27.08.2018perf record
для подсчета следующих трех событий:CORE_POWER.LVL0_TURBO_LICENSE
,CORE_POWER.LVL1_TURBO_LICENSE
иCORE_POWER.LVL2_TURBO_LICENSE
. Затемperf report
разбивает его на изображения в формате ELF. Выполнение чего-то подобного позволит вам закрепить изображение в формате ELF. Затем следует статический бинарный анализ. Хотя раньше я не использовал эти события perf. - person Hadi Brais   schedule 28.08.2018zmm[0-3]
. - person Peter Cordes   schedule 01.09.2018