снижение производительности при включении PTI = в Linux-4.4.0 - PullRequest
0 голосов
/ 13 июня 2018

Я выполняю тест Java на Ubuntu 16.04 и обнаружил разницу в производительности при включенном и выключенном PTI.
Моя хост-система использует процессор Ivybridge (2cores, 4 HT) 1,6 ГГц с памятью 16 ГБ.

Я попытался использовать perf для анализа, откуда берется разница, следующим образом.

С pti = off в grub.cfg,

# perf  stat -e bus-cycles,cache-misses,cache-references,L1-dcache-load-misses,dTLB-load-misses,L1-dcache-prefetch-misses,LLC-prefetches ./test.sh 

 Performance counter stats for './test.sh':

       774,986,827      bus-cycles                                                    (59.13%)
        24,044,906      cache-misses              #   12.803 % of all cache refs      (58.17%)
       187,799,652      cache-references                                              (57.51%)
       207,345,039      L1-dcache-load-misses                                         (57.65%)
        13,081,612      dTLB-load-misses                                              (58.85%)
        22,678,453      L1-dcache-prefetch-misses                                     (59.62%)
        24,089,506      LLC-prefetches                                                (59.99%)

       6.210151360 seconds time elapsed

и, сpti = on (настройки по умолчанию в ядре Linux), я получил,

# perf stat -e bus-cycles,cache-misses,cache-references,L1-dcache-load-misses,dTLB-load-misses,L1-dcache-prefetch-misses,LLC-prefetches ./test.sh 

Статистика счетчика производительности для './test.sh':

 1,205,903,578      bus-cycles                                                    (57.92%)
    23,877,107      cache-misses              #   13.167 % of all cache refs      (57.31%)
   181,340,147      cache-references                                              (57.46%)
   206,177,901      L1-dcache-load-misses                                         (58.42%)
    63,285,591      dTLB-load-misses                                              (59.06%)
    24,012,988      L1-dcache-prefetch-misses                                     (58.65%)
    24,928,410      LLC-prefetches                                                (58.23%)

  10.344839116 seconds time elapsed  

test.sh - это программаДля профилирования, из вышеприведенного вывода perf, test.sh занял больше времени с pti = on, чем с pti = off, но вывод события НЕ ясен, откуда берется разница.
Есть ли какое-либо другое событие perf, которое может помочь в этомдело ?

Обновлено с большим количеством перф события.
PTI = выкл

# perf stat --repeat 5 -e cache-references,cache-misses,cpu-cycles,ref-cycles,faults,L1-dcache-loads,L1-dcache-load-misses,L1-icache-load-misses,branches,branch-misses,node-loads,node-load-misses,instructions,cs java mytest

 Performance counter stats for 'java mytest' (5 runs):

         8,711,306      cache-references                                              ( +-  4.13% )  (48.49%)
         1,290,234      cache-misses              #   14.811 % of all cache refs      ( +-  4.04% )  (49.44%)
       709,587,381      cpu-cycles                                                    ( +-  1.44% )  (48.91%)
       671,299,480      ref-cycles                                                    ( +-  1.95% )  (58.09%)
             5,918      faults                                                        ( +-  0.12% )
       185,928,475      L1-dcache-loads                                               ( +-  4.29% )  (35.90%)
         9,249,983      L1-dcache-load-misses     #    4.98% of all L1-dcache hits    ( +-  5.91% )  (27.84%)
         4,718,632      L1-icache-load-misses                                         ( +-  5.47% )  (20.83%)
       106,021,866      branches                                                      ( +-  1.98% )  (31.56%)
         4,487,091      branch-misses             #    4.23% of all branches          ( +-  5.35% )  (40.34%)
           450,170      node-loads                                                    ( +-  9.18% )  (38.32%)
                 0      node-load-misses                                              (40.62%)
       509,344,631      instructions              #    0.72  insns per cycle          ( +-  5.59% )  (49.64%)
               458      cs                                                            ( +-  2.05% )

       0.216794242 seconds time elapsed                                          ( +-  3.44% )   

PTI = ON

# perf stat --repeat 5 -e cache-references,cache-misses,cpu-cycles,ref-cycles,faults,L1-dcache-loads,L1-dcache-load-misses,L1-icache-load-misses,branches,branch-misses,node-loads,node-load-misses,instructions,cs java mytest

 Performance counter stats for 'java mytest' (5 runs):

        10,109,469      cache-references                                              ( +-  4.10% )  (44.67%)
         1,360,012      cache-misses              #   13.453 % of all cache refs      ( +-  2.16% )  (45.28%)
     1,199,960,141      cpu-cycles                                                    ( +-  2.44% )  (46.13%)
     1,086,243,141      ref-cycles                                                    ( +-  1.28% )  (54.64%)
             5,923      faults                                                        ( +-  0.24% )
       163,902,394      L1-dcache-loads                                               ( +-  3.46% )  (41.91%)
         8,588,505      L1-dcache-load-misses     #    5.24% of all L1-dcache hits    ( +-  5.59% )  (27.82%)
         5,576,811      L1-icache-load-misses                                         ( +-  3.87% )  (18.41%)
       117,508,300      branches                                                      ( +-  3.98% )  (27.34%)
         4,878,640      branch-misses             #    4.15% of all branches          ( +-  2.28% )  (35.55%)
           585,464      node-loads                                                    ( +-  9.05% )  (34.55%)
                 0      node-load-misses                                              (36.68%)
       614,773,322      instructions              #    0.51  insns per cycle          ( +-  4.11% )  (46.10%)
               476      cs                                                            ( +-  2.75% )

       0.375871969 seconds time elapsed                                          ( +-  0.81% )

1 Ответ

0 голосов
/ 13 июня 2018

Понятия не имею, что на самом деле измеряет событие "циклы шины".тактовые частоты ядра обычно более актуальны.

Но в любом случае, PTI = on делает каждый системный вызов (и другую запись в ядре) более дорогим, потому что он должен модифицировать регистр управления x86 CR3 (установка новой страницы).указатель верхнего уровня таблицы).Это буквально то, как оно изолирует пространство пользователя от доступа к таблицам страниц ядра.

Обратите внимание на значительное увеличение dTLB-load-misses.Благодаря поддержке идентификаторов контекста процесса (PCID) PTI может избежать полной очистки TLB при каждом входе в ядро.Но я не знаю деталей.(Без PCID замена таблиц страниц делает недействительным весь TLB.)

Вы можете использовать strace -c для определения времени системных вызовов.

С perf record (с достаточными привилегиями) вы можете записыватьпримеры, которые включают код ядра, так что вы можете увидеть, какие инструкции в ядре на самом деле заняли много времени.(Перемещение к CR3 также требует времени, и то же самое относится и к смягчению Спектра, которое отделено от смягчения Meltdown (PTI). Но я думаю, что большинство стоимости смягчения Meltdown заключается в том, что TLB со временем пропускает ядрои снова после возврата в пользовательское пространство, а не из таблиц перестановки страниц.)

...