Измерение времени выполнения является важным аспектом оценки производительности. Теперь я хочу оценить производительность нескольких кодов внутри анклава SGX (доверенной среды выполнения), и я заметил, что Intel SGX предоставляет API под названием «sgx_get_trusted_time()», чтобы разработчики могли получать текущее время из надежного источника. Однако тут у меня возникли проблемы:
1) «sgx_create_pse_session()» требуется перед использованием «sgx_get_trusted_time()», но я всегда получал ошибку «SGX_ERROR_SERVICE_UNAVAILABLE». Я правильно установил и настроил SGX SDK и PSW (в противном случае я не могу использовать службу удаленной аттестации). Я также пытался обновить Management Engine для платформы разработки (Win10 + ThinkPad x270 + CORE i5), но это не сработало;
2) API возвращает время в секундах, что далеко не точно с точки зрения оценки производительности, особенно когда время, прошедшее между двумя вызовами API, тривиально.
Как я могу решить первую проблему и какое-либо решение для более точного измерения времени, прошедшего внутри анклава? Признателен за любое предложение или намек.
rdtsc
внутри анклава? Если это так, вы можете записать это внутри анклава и разместить где-нибудь, чтобы вы могли видеть снаружи. Как получить количество циклов ЦП в x86_64 из C++?. Он настолько точен, насколько это возможно для x86 (толькоrdpmc
для аппаратных счетчиков производительности меньше накладных расходов), но он по-прежнему имеет накладные расходы в десятки тактовых циклов. И TSC тикает с постоянной частотой, поэтому вам нужно контролировать такты турбо / холостого хода. Смотрите мой ответ на этот вопрос. - person Peter Cordes   schedule 04.05.2020add eax, [rdi]
, а не вызов функции другого кода. Однако он микрокодирован, поэтому его можно обрабатывать особым образом в зависимости от режима. (Это есть или может быть для виртуальных машин). software.intel.com/ en-us/forums/ сообщает, что RDTSC и RDTSCP разрешены внутри анклава для процессоров, поддерживающих SGX2 (с учетом значения CR4.TSD). - person Peter Cordes   schedule 06.05.2020int foo = a + b;
, из встроенных функций, таких какlong foo = __rdtsc();
, или из встроенного ассемблера. Так что нет, вам не нужно писать программу на ассемблере! 2. Да, в конце концов, дело только в том, какие инструкции процессора разрешены при выполнении в режиме SGX. Очевидно, это не всегда включаетrdtsc
. - person Peter Cordes   schedule 07.05.2020__rdtsc()
всегда будет увеличиваться на 1 за цикл ссылки. Абсолютное значение начинается с0
при сбросе ЦП, если с тех пор оно не менялось. Аппаратная виртуализация Intel/AMD может масштабировать и смещать гостевой TSC, и я думаю, что ядро может написать TSC для его сброса через MSR (регистр для конкретной модели). Но это не возможный вектор атаки на ваш реальный код, если вы удалите код бенчмаркинга rdtsc из реального приложения. - person Peter Cordes   schedule 07.05.2020uint64_t start = __rdtsc();
/ делать вещи /uint64_t duration = __rdtsc() - start;
. См. Как получить количество циклов ЦП в x86_64 из C++? для получения дополнительной информации, включая некоторые предостережения по этому поводу в моем ответе. Если материал очень короткий, вы можете убедиться, что выполнение более ранних инструкций завершено с помощью_mm_lfence(); duration = __rdtsc() - start;
, в противном случае exec не по порядку может запустить rdtsc до того, как работа, которую вы рассчитываете, будет завершена. Время будет в эталонных циклах, а не в абсолютных наносекундах. - person Peter Cordes   schedule 07.05.2020intrin.h
? Я никогда ничего не делал с SGX, я здесь только для тегов intel/x86. Я немного знаю об этом как о режиме ЦП, потому что знаю о x86 ISA / сборке, но ничего об инструментах для создания приложений SGX. Надеюсь, кто-то еще заметит ваш вопрос и ответит на него; Я изменил тег[x86]
, и, надеюсь, это заметит больше людей. - person Peter Cordes   schedule 07.05.2020__rdtsc
вintrin.h
и скопировать его в свое приложение SGX. Или, если вы компилируете для 32-битного режима, вы могли бы использовать встроенный ассемблер MSVC. (Встроенная поддержка asm в MSVC была настолько неуклюжей, что ее отключили для 64-битного режима.) - person Peter Cordes   schedule 07.05.2020printf
из анклава или любую другую функцию, объявленную вstdio.h
. Но я думаю, что все вintrin.h
можно просто встроить в машинную инструкцию. Например,_popcnt_u32(x)
можно вычислить с помощью цикла или битхаков; его запрет аналогичен запрету оператора C++*
умножения для целых чисел: вы можете легко программировать без него, просто менее удобно использовать цикл сдвига/сложения, а не более безопасный - person Peter Cordes   schedule 07.05.2020intrin.h
есть некоторые вещи, которые имеет смысл не предоставлять, но тогда в качестве побочного эффекта вы теряете доступ к другим вещам. Например, rdtsc и rdrand - это не то, что вы могли бы просто вычислить другим способом, поэтому, возможно, есть какая-то причина их запретить. (По-видимому, SGX полностью запрещал rdtsc до SGX2, а затем только с правильной настройкой в управляющем регистре; IDK, что для этого по умолчанию). В общем, для MSVC может иметь смысл защитить вас от вас самих, не позволяя некоторым встроенным функциям находиться в анклаве, но это выбор Microsoft, а не Intel. - person Peter Cordes   schedule 07.05.2020rdtsc
в машинный код вашего анклава, скопировав некоторые строки изintrin.h
в ваш собственный заголовок. Я попробовал на Godbolt, используя-E
, чтобы заставить компилятор выводить содержимое заголовочного файла. Там есть прототипunsigned __int64 __rdtsc(void);
, но использование его вручную просто заставляет его скомпилировать вызов функции с этим именем, а не встроенную инструкциюrdtsc
. godbolt.org/z/n3BhEy. Какая-то другая строка должна позволять распознавать его как встроенный компилятор. - person Peter Cordes   schedule 07.05.2020