5

Я разработал код, который получает в качестве входных данных большой 2-D изображение (до 64MPixels) и:Интерпретация вывода перфорация стат

  • применяет фильтры на каждой строке
  • Транспонирует изображение (используется блокировки, чтобы избежать многих промахов кэша)
  • применяет фильтры на колоннах (теперь-строки) изображения
  • переставляет отфильтрованное изображение обратно, чтобы продолжить с другими расчетами

Хотя это ничего не меняет, для полноты моего вопроса фильтрация применяет дискретное вейвлет-преобразование, а код записывается в C.

Моя конечная цель - сделать так быстро, как возможное. Ускорение, которое у меня есть до сих пор, более чем в 10 раз за счет использования матрицы блокировки, транспонирования, векторизации, многопоточности, компилятора кода и т. Д.

На мой вопрос: последние профилирующие данные кода, который у меня есть (с использованием perf stat -e) беспокоили меня.

 76,321,873 cache-references            
    8,647,026,694 cycles     # 0.000 GHz      
    7,050,257,995 instructions    # 0.82 insns per cycle   
     49,739,417 cache-misses    # 65.171 % of all cache refs  

     0.910437338 seconds time elapsed 

(# of cache-misses)/(# инструкция) низкий примерно ~ 0.7%. Here упоминается, что это число - хорошая вещь, чтобы иметь в виду проверку эффективности памяти.

С другой стороны,% пропусков кеша к кеш-ссылкам значительно выше (65%!), Что, как я вижу, может указывать на то, что что-то не так с исполнением с точки зрения эффективности кеша.

подробная статистика из perf stat -d является:

2711.191150 task-clock    # 2.978 CPUs utilized   
     1,421 context-switches   # 0.524 K/sec     
      50 cpu-migrations   # 0.018 K/sec     
     362,533 page-faults    # 0.134 M/sec     
8,518,897,738 cycles     # 3.142 GHz      [40.13%] 
6,089,067,266 stalled-cycles-frontend # 71.48% frontend cycles idle [39.76%] 
4,419,565,197 stalled-cycles-backend # 51.88% backend cycles idle [39.37%] 
7,095,514,317 instructions    # 0.83 insns per cycle   
             # 0.86 stalled cycles per insn [49.66%] 
    858,812,708 branches     # 316.766 M/sec     [49.77%] 
    3,282,725 branch-misses    # 0.38% of all branches   [50.19%] 
1,899,797,603 L1-dcache-loads   # 700.724 M/sec     [50.66%] 
    153,927,756 L1-dcache-load-misses  # 8.10% of all L1-dcache hits [50.94%] 
    45,287,408 LLC-loads     # 16.704 M/sec     [40.70%] 
    26,011,069 LLC-load-misses   # 57.44% of all LL-cache hits [40.45%] 

    0.910380914 seconds time elapsed 

Здесь и во внешнем интерфейсе Серверные застопорился циклы также высоки и нижние кэши уровня, кажется, страдает от высокой скорости промаха 57,5%.

Какая метрика является наиболее подходящей для этого сценария? Одна из идей, о которых я подумал, заключается в том, что это может быть так, что рабочая нагрузка больше не требует дальнейшего «касания» кэшей LL после начальной загрузки изображения (загружает значения один раз и после этого это делается - рабочая нагрузка больше связана с ЦП, чем связанный с памятью, являющийся алгоритмом фильтрации изображений).

Машина, на которой я запускаю это, представляет собой Xeon E5-2680 (20M Smart-кеш, из которого кеш L2 на 256 КБ на ядро, 8 ядер).

+0

koukouviou, 'perf stat -d' может быть неточным, может быть полезно повторить его несколько раз с 4-5 событиями за ход,' perf stat -e L1-dcache-load, L1-dcache-load-misses , ООО загружает, ООО загружает-misses'. Если ваши этапы могут быть разделены, вы можете измерить каждый этап, чтобы найти, какой из них генерирует промахи. Или вы можете запустить 'perf record -e cache-misses', чтобы получить профиль кода, который имеет большинство промахов (как было рекомендовано в [« Здесь »] (http://developerblog.redhat.com/2014/03/10/ определение-ли-приложение-имеет-плохой кэш-производительность-2 /), с которым вы связаны). – osgx

+0

@osgx Я сделал тесты, которые вы упомянули, но почта была уже длинной, поэтому я держал ее как можно более кратким. Хотя статистика немного изменилась, по-прежнему статистически схож с высокими промахами кеша%. Я запустил перформанс/отчет/аннотацию, а промахи приписываются в основном ядрам-kallsyms, но я не знаю, что из этого делать ... – koukouviou

+0

koukouviou, вы можете повторно запустить свой stat со всеми событиями, space: 'perf stat -e event1: u, event2: u, ...' и сравнить с опубликованными результатами (по умолчанию измеряются как пользователь, так и ядро). kernel-kallsyms означают, что некоторые функции из пространства ядра имели это событие ... Некоторые возможные проблемы с неизвестными/неразрешенными символами перечислены здесь: http://www.brendangregg.com/blog/2014-06-22/perf-cpu -sample.html. Я не могу дать вам советы по метрикам .... – osgx

ответ

3

Первое, что вы хотите убедиться, это то, что никакой другой процесс интенсивного вычисления не работает на вашей машине. Это серверный процессор, поэтому я подумал, что это может быть проблемой.

Если вы используете многопоточность в своей программе и вы распределяете равный объем работы между потоками, вам может быть интересно, что собирает метрики только на одном CPU.

Я предлагаю отключить гиперпоточность в фазе оптимизации, так как это может привести к путанице при интерпретации показателей профилирования. (например, увеличение # циклов, проведенных в фоновом режиме). Кроме того, если вы распространяете работу на 3 потока, у вас есть большая вероятность, что 2 потока будут делиться ресурсами одного ядра, а третий будет иметь все ядро ​​для себя - и это будет быстрее.

Перф никогда не очень хорошо объяснял показатели. Судя по порядку величины, ссылки на кеш - это промахи L2, попавшие в LLC. Высокий номер пропуска LLC по сравнению с ссылками на LLC не всегда является плохим, если количество ссылок на LLC/#Instructions низкое. В вашем случае у вас 0,018, поэтому это означает, что большинство ваших данных используется из L2. Высокий коэффициент пропускания LLC означает, что вам все равно нужно получать данные из ОЗУ и записывать их обратно.

Относительно #Cycles BE и FE связаны, меня немного беспокоят значения, потому что они не суммируются до 100% и общего количества циклов. У вас 8G, но они остаются 6G циклов в циклах FE и 4G в BE. Это не кажется очень правильным.

Если FE-цикл является высоким, это означает, что у вас есть промахи в кеше инструкций или в предположениях о неправильной ветви. Если цикл BE высокий, это означает, что вы ждете данных.

В любом случае, относительно ваш вопрос. Наиболее подходящей метрикой для оценки производительности вашего кода является Инструкции/Цикл (IPC). Ваш процессор может выполнять до 4 инструкций/циклов. Вы выполняете только 0,8. Это означает, что ресурсы недоиспользуются, за исключением случаев, когда у вас есть много векторных инструкций. После IPC вам нужно проверить пропуски ветвей и промахи L1 (данные и код), поскольку они генерируют большинство штрафов.

Окончательное предложение: вам может быть интересно попробовать Intel vTune Amplifier. Это дает гораздо лучшее объяснение метрик и указывает на возможные проблемы в вашем коде.

+1

VAndrei, BE и FE киоски никогда не будут суммироваться с инструкциями на 100% циклов, потому что большинство процессоров Intel являются суперпипелированными. Многие инструкции могут находиться в полете по трубопроводу, а некоторые из них будут создавать киоски; но некоторые будут выполнены. 71% FE stalls высок (у вас много кода, который сложно декодировать?) И 51% BE киосков тоже слишком высоки - так что есть несколько проблем ... koukouviou, вы также можете попробовать 'toplev.py' из [andikleen/pmu-tools (github)] (https://github.com/andikleen/pmu-tools) как бесплатный паллиативный для Vtune. – osgx

+0

koukouviou, 'toplev.py' описание от автора - http://halobates.de/blog/p/262 – osgx

+0

@osgx. Я не уверен в этом. FE означает, что блок резервирования не снабжен инструкциями, поэтому рабочие порты выполнения не работают. Это из-за промахов кода, сложных инструкций и плохой спекуляции. Если BE является высоким, это означает, что инструкции поддерживают занятые порты выполнения, но они ждут ресурсов (данных или свободных регистров) или имеют высокие задержки (например, transcedentals). Должна быть еще одна метрика: #cycles retired. Если вы посмотрите на vTune, вы увидите, что FE + BE + Ret Ret добавляет 100% всегда. – VAndrei

Смежные вопросы