Я пытаюсь создать на мой Kabe lake 7600U, я использую CentOS 7.
Полный тестовый репозиторий доступен на GitHub.
Моя версия спецполина выглядит следующим образом (cfr. spec.asm ):
specpoline:
;Long dependancy chain
fld1
TIMES 4 f2xm1
fcos
TIMES 4 f2xm1
fcos
TIMES 4 f2xm1
%ifdef ARCH_STORE
mov DWORD [buffer], 241 ;Store in the first line
%endif
add rsp, 8
ret
Эта версия отличается от версии Генри Вонга тем, что поток отклоняется на архитектурный путь. В то время как исходная версия использовала фиксированный адрес, я передаю цель в стек.
Таким образом, add rsp, 8
удалит исходный адрес возврата и использует искусственный.
В первой части функции я создаю длинную цепочку зависимостей с задержкой, используя некоторые старые инструкции FPU, затем независимую цепочку, которая пытается обмануть предсказатель стека возврата ЦП.
Описание кода
Спецполин вставляется в контекст профилирования с помощью FLUSH+RELOAD1, тот же файл сборки также содержит:
buffer
Непрерывный буфер, охватывающий 256 отдельных строк кэша, каждая из которых разделена GAP-1
строками, всего 256*64*GAP
байт.
GAP используется для предотвращения аппаратной предварительной выборки.
Далее следует графическое изображение (каждый индекс идет сразу после другого).
timings
Массив из 256 DWORD, каждая запись содержит время в циклах ядра, необходимое для доступа к соответствующей строке в буфере F+R.
flush
Небольшая функция для касания каждой страницы (с сохранением, просто чтобы убедиться, что COW на нашей стороне) буфера F+R и вытеснения обозначенных строк.
'профиль'
Стандартная функция профиля, которая использует lfence+rdtsc+lence
скважину для профилирования нагрузки от каждой линии в буфере F+R и сохраняет результат в массиве timings
.
leak
Это функция, которая выполняет настоящую работу, вызовите функцию specpoline
, помещающую хранилище в спекулятивный путь, и функцию profile
в архитектурный путь.
;Flush the F+R lines
call flush
;Unaligned stack, don't mind
lea rax, [.profile]
push rax
call specpoline
;O.O 0
; o o o SPECULATIVE PATH
;0.0 O
%ifdef SPEC_STORE
mov DWORD [buffer], 241 ;Just a number
%endif
ud2 ;Stop speculation
.profile:
;Ll Ll
; ! ! ARCHITECTURAL PATH
;Ll Ll
;Fill the timings array
call profile
Для начальной загрузки тестовой системы используется небольшая программа на C.
Запуск тестов
В коде используются условные препроцессоры для условного помещения хранилища в архитектурный путь (фактически в саму спецификацию), если определено ARCH_STORE
, и для условного помещения хранилища в спекулятивный путь, если определено SPEC_STORE
.
Оба сохраняют доступ к первой строке буфера F+R.
Запуск make run_spec
и make run_arch
соберет spec.asm
с соответствующим символом, скомпилирует тест и запустит его.
Тест показывает тайминги для каждой строки буфера F+R.
Сохранить в архитектурном пути
38 230 258 250 212 355 230 223 214 212 220 216 206 212 212 234
213 222 216 212 212 210 1279 222 226 301 258 217 208 212 208 212
208 208 208 216 210 212 214 213 211 213 254 216 210 224 211 209
258 212 214 224 220 227 222 224 208 212 212 210 210 224 213 213
207 212 254 224 209 326 225 216 216 224 214 210 208 222 213 236
234 208 210 222 228 223 208 210 220 212 258 223 210 218 210 218
210 218 212 214 208 209 209 225 206 208 206 1385 207 226 220 208
224 212 228 213 209 226 226 210 226 212 228 222 226 214 230 212
230 211 226 218 228 212 234 223 228 216 228 212 224 225 228 226
228 242 268 226 226 229 224 226 224 212 299 216 228 211 226 212
230 216 228 224 228 216 228 218 228 218 227 226 230 222 230 225
228 226 224 218 225 252 238 220 229 1298 228 216 228 208 230 225
226 224 226 210 238 209 234 224 226 255 230 226 230 206 227 209
226 224 228 226 223 246 234 226 227 228 230 216 228 211 238 216
228 222 226 227 226 240 236 225 226 212 226 226 226 223 228 224
228 224 229 214 224 226 224 218 229 238 234 226 225 240 236 210
Хранить на предполагаемом пути
298 216 212 205 205 1286 206 206 208 251 204 206 206 208 208 208
206 206 230 204 206 208 208 208 210 206 202 208 206 204 256 208
206 208 203 206 206 206 206 206 208 209 209 256 202 204 206 210
252 208 216 206 204 206 252 232 218 208 210 206 206 206 212 206
206 206 206 242 207 209 246 206 206 208 210 208 204 208 206 204
204 204 206 210 206 208 208 232 230 208 204 210 1287 204 238 207
207 211 205 282 202 206 212 208 206 206 204 206 206 210 232 209
205 207 207 211 205 207 209 205 205 211 250 206 208 210 278 242
206 208 204 206 208 204 208 210 206 206 206 206 206 208 204 210
206 206 208 242 206 208 206 208 208 210 210 210 202 232 205 207
209 207 211 209 207 209 212 206 232 208 210 244 204 208 255 208
204 210 206 206 206 1383 209 209 205 209 205 246 206 210 208 208
206 206 204 204 208 246 206 206 204 234 207 244 206 206 208 206
208 206 206 206 206 212 204 208 208 202 208 208 208 208 206 208
250 208 214 206 206 206 206 208 203 279 230 206 206 210 242 209
209 205 211 213 207 207 209 207 207 211 205 203 207 209 209 207
Поставил хранилище в архитектурный путь для проверки функции таймингов, вроде работает.
Однако я не могу получить тот же результат с хранилищем на спекулятивном пути.
Почему ЦП не выполняет хранилище спекулятивно?
1 Признаюсь, я никогда не тратил время на изучение всех методов профилирования кеша. Надеюсь, я использовал правильное имя. Под FLUSH+RELOAD я подразумеваю процесс вытеснения набора строк, спекулятивного выполнения некоторого кода, а затем записи времени доступа к каждой из вытесненных строк.
sqrtpd
, вероятно, будет вашим лучшим выбором. - person Peter Cordes   schedule 06.04.2019sqrtpd
с аналогичными результатами. Однако я не инициализировал регистр XMM, используемый в качестве ввода (и вывода), думая, что это не имеет значения. Я проверил еще раз, но на этот раз я инициализировал регистр двумя двойными значениями1e200
, и то, что я получаю, является прерывистым результатом. Иногда строка выбирается спекулятивно, иногда нет. Похоже, чтоmovups xmm0, [...]
, за которыми следуют десятьsqrtpd xmm0, xmm0
, является лучшей комбинацией, хотя и не на 100% надежной. Здесь немного поздно, я обновлю ответ завтра. Спасибо за отзыв! - person Margaret Bloom   schedule 06.04.2019