Этот вопрос продолжает мой вопрос здесь (по совету Mystical):
Производительность цикла кода C
Продолжая свой вопрос, когда я использую упакованные инструкции вместо скалярных инструкций, код, использующий встроенные функции, будет выглядеть очень похоже:
for(int i=0; i<size; i+=16) {
y1 = _mm_load_ps(output[i]);
…
y4 = _mm_load_ps(output[i+12]);
for(k=0; k<ksize; k++){
for(l=0; l<ksize; l++){
w = _mm_set_ps1(weight[i+k+l]);
x1 = _mm_load_ps(input[i+k+l]);
y1 = _mm_add_ps(y1,_mm_mul_ps(w,x1));
…
x4 = _mm_load_ps(input[i+k+l+12]);
y4 = _mm_add_ps(y4,_mm_mul_ps(w,x4));
}
}
_mm_store_ps(&output[i],y1);
…
_mm_store_ps(&output[i+12],y4);
}
Измеренная производительность этого ядра составляет около 5,6 операций FP за цикл, хотя я ожидаю, что она будет ровно в 4 раза выше производительности скалярной версии, то есть 4,1,6 = 6,4 операций FP за цикл.
С учетом изменения весового коэффициента (спасибо, что указали на это) график выглядит так:
Похоже, расписание не меняется, хотя после movss
операции которая перемещает значение скалярного веса в регистр XMM, а затем использует shufps
для копирования этого скалярного значения во весь вектор. Похоже, что весовой вектор готов к использованию на mulps
время, учитывая задержку переключения с нагрузки на домен с плавающей запятой, поэтому это не должно приводить к дополнительной задержке.
movaps
(Выровнены, упакованный ход),addps
и mulps
инструкция, которые используются в этом ядре (проверен с ассемблером) имеет одинаковую задержку & пропускную способность, как и их скалярные версии, поэтому это не должно брать на себя какие - либо дополнительные задержки либо.
Кто-нибудь знает, на что тратится этот дополнительный цикл из 8 циклов, если максимальная производительность, которую может получить это ядро, составляет 6,4 операций FP за цикл, и оно работает со скоростью 5,6 операций FP за цикл?
Кстати вот как выглядит фактическая сборка:
…
Block x:
movapsx (%rax,%rcx,4), %xmm0
movapsx 0x10(%rax,%rcx,4), %xmm1
movapsx 0x20(%rax,%rcx,4), %xmm2
movapsx 0x30(%rax,%rcx,4), %xmm3
movssl (%rdx,%rcx,4), %xmm4
inc %rcx
shufps $0x0, %xmm4, %xmm4 {fill weight vector}
cmp $0x32, %rcx
mulps %xmm4, %xmm0
mulps %xmm4, %xmm1
mulps %xmm4, %xmm2
mulps %xmm3, %xmm4
addps %xmm0, %xmm5
addps %xmm1, %xmm6
addps %xmm2, %xmm7
addps %xmm4, %xmm8
jl 0x401ad6 <Block x>
…
shufps
инструкция добавляет 1 цикл каждые 1,6 итераций?» Это сложный вопрос ...shufps
должен быть напрямую доступенmultps
оператору, поскольку это оба домена FPОтветы:
Попробуйте использовать профилирование EMON в Vtune или другой аналогичный инструмент, например oprof
Профилирование EMON (мониторинг событий) => похоже на инструмент, основанный на времени, но он может сказать вам, какое событие производительности вызывает проблему. Тем не менее, вы должны сначала начать с профиля, основанного на времени, чтобы увидеть, нет ли конкретной инструкции, которая выскакивает. (И, возможно, связанные события, которые говорят вам, как часто на этом IP-адресе была пенсионная палатка.)
Чтобы использовать профилирование EMON, вы должны просмотреть список событий, от «обычных подозреваемых» до ...
Здесь я бы начал с промахов кеша, выравнивания. Я не знаю, есть ли у процессора, который вы используете, счетчик ограничений RF-порта - он должен - но я давно добавил профилирование EMON, и я не знаю, насколько хорошо они справляются с добавлением событий, подходящих для микроархитектуры.
Также возможно, что это интерфейс, выборка инструкций, задержка. И вообще, сколько байтов в этих инструкциях? Для этого тоже есть мероприятия EMON.
Ответ на комментарий о том, что Nehalem VTune не может видеть события L3: неправда. Вот что я добавил в комментарий, но не подошел:
Собственно, счетчики производительности для LL3 / L3 $ / так называемого Uncore ЕСТЬ. Я был бы безмерно удивлен, если VTune их не поддержит. Видеть Http://software.intel.com/sites/products/collateral/hpc/vtune/performance_analysis_guide.pdf.указывает на VTune и другие инструменты, такие как PTU. Фактически, даже без событий LL3, как говорит Дэвид Левинталь: «процессор Intel® Core ™ i7 имеет« событие задержки », которое очень похоже на событие EAR данных семейства процессоров Itanium®. Это событие производит выборки загрузок, записывая количество циклы между выполнением инструкции и фактической доставкой данных. Если измеренная задержка больше, чем минимальная задержка, запрограммированная в MSR 0x3f6, биты 15: 0, то значение счетчика увеличивается. Переполнение счетчика включает механизм PEBS и на следующем событие, удовлетворяющее порогу задержки, измеренная задержка, виртуальный или линейный адрес и источник данных копируются в 3 дополнительных регистра в буфере PEBS. Поскольку виртуальный адрес фиксируется в известном месте, драйвер выборки также может выполнять преобразование виртуального в физический и захватывать физический адрес. Физический адрес идентифицирует домашнее местоположение NUMA и в принципе позволяет анализировать детали занятости кеша ». На странице 35 он также указывает на такие события VTune, как L3 CACHE_HIT_UNCORE_HIT и L3 CACHE_MISS_REMOTE_DRAM. Иногда вам нужно искать числовые коды и запрограммировать их в интерфейс нижнего уровня VTune, но я думаю, что в этом случае это видно в красивом пользовательском интерфейсе.
Хорошо, в http://software.intel.com/en-us/forums/showthread.php?t=77700&o=d&s=lr программист VTune в России (я думаю) "объясняет", что вы не можете семплировать на Uncore События.
Он ошибается - вы можете, например, включить только один процессор и выполнять сэмплы осмысленно. Я также считаю, что есть возможность отмечать недостающие данные L3, когда они возвращаются в ЦП. Фактически, в целом L3 знает, на какой процессор он возвращает данные, поэтому вы определенно можете выполнить выборку. Вы можете не знать, какой именно гиперпоток, но снова можете отключить, перейти в однопоточный режим.
Но похоже, что, как это часто бывает, вам придется работать ВОКРУГ VTune, а не с ним, чтобы сделать это.
Сначала попробуйте профилирование задержки. Это полностью внутри ЦП, и люди из VTune вряд ли слишком сильно его испортили.
И, повторяю еще раз, вероятно, что ваша проблема в ядре, а не в L3. Так что VTune должен с этим справиться.
Попробуйте «Учет цикла» по Левинталю.
источник
off-core
части ядра, поэтому для этой части нет доступных счетчиков событий производительности. Поэтому сложно оценить промахи в кэше и так далее.