#c #x86 #cpu-cache #microbenchmark #hyperthreading
# #c #x86 #cpu-cache #микробенчмарк #гиперпоточность
Вопрос:
Когда я использовал Hyper-Threading
, появилось очень странное явление. Я использовал язык c для измерения времени l2 hit
. Я написал время тестирования в программе A
. Когда я запускаю его в одиночку, он показал, что это занимает примерно 26 cycles
каждый раз. Когда я писал другую программу, B. привязывался B
и A
к тому же ядру и запускался в виде гиперпоточности. Даже если на B был написан только бесполезный цикл, например:
for(;;){
}
Я обнаружил, что в этом случае, когда я A
снова запускаю программу, отображаемое L2 hit
время становится примерно 10
равным.
Код очень длинный. Псевдокод теста выглядит следующим образом.
A:
Select 16 cache lines (line 0 -16)in a set. // l1 cache is VIPT structure
Organize the disordered sequence of line0 to line8 into a linked list to prevent prefetching.
Organize the disordered sequence of line9 to line15 into a linked list to prevent prefetching.
load line 0 - 8 //Because it is a linked list, it is read serially
fence()
t1= rdtscp()
load line 9 - 15 //Because it is a linked list, it is read serially
t2 = rdtscp()
print t2 - t1
B : for(;;){
}
Когда выполняется только A, результат вывода в среднем равен 200. Когда B и A выполняются с одним и тем же гиперпоточным ядром, выходной результат A равен 90.
Если эффект гиперпоточности увеличивает время, я могу это понять, возможно, это помехи, но в чем причина сокращения времени?
Конфигурация моего сервера выглядит следующим образом:
Linux version 4.15.0-122-generic (buildd@lcy01-amd64-010) (gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.12)) #124~16.04.1-Ubuntu SMP
Комментарии:
1. Задержка попадания Skylake L2 составляет около 12 циклов. Если вы измеряли 26, возможно, ваш процессор не разогнался до тактовой частоты ядра, аналогичной эталонной тактовой частоте RDTSC? (Даже тогда это не точно.) Запуск другого потока (и выполнение бесконечного цикла) может дать больше времени для разгона процессора.
2. Я думаю, вы правы. Когда я повторно запускаю alone, я сбрасываю его, чтобы привязать к ядру, и теперь результат нормальный.