Производительность цикла кода C [продолжение]

Этот вопрос продолжается по моему вопросу здесь (по совету Мистического):

Производительность цикла кода 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> 
…

1 ответ

Попробуйте использовать профилирование EMON в Vtune или другой эквивалентный инструмент, такой как oprof

EMON (Event Monitoring) profiling => похож на инструмент, основанный на времени, но он может сказать вам, какое событие производительности вызывает проблему. Хотя сначала вы должны начать с профиля, основанного на времени, чтобы увидеть, выпадает ли какая-то конкретная инструкция. (И, возможно, связанные с этим события, которые говорят вам о том, как часто на этом IP происходил выход на пенсию)

Чтобы использовать профилирование EMON, вы должны просмотреть список событий, начиная от "обычных подозреваемых" до…

Здесь я бы начал с промахов кэша, выравнивания. Я не знаю, есть ли у используемого вами счетчика счетчик ограничений RF-порта - он должен - но я давно добавил профилирование EMON, и я не знаю, насколько хорошо они справляются, добавляя события, подходящие для микроархитектуры.

Также возможно, что это внешний интерфейс, выборка команд, остановка. В любом случае, сколько байтов в этих инструкциях? Для этого тоже есть события EMON.


Отвечая на комментарий, что Nehalem VTune не может видеть события L3: не верно. Вот что я добавлял в комментарии, но не подходил:

На самом деле, есть счетчики производительности ARE для 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, когда они возвращаются в CPU. Фактически, в целом L3 знает, на какой процессор он возвращает данные, так что вы можете определенно выполнить выборку. Вы можете не знать, какая гиперпотока, но опять же вы можете отключить, перейти в однопотоковый режим.

Но, похоже, что, как правило, вам придется работать вокруг VTune, а не с ним, чтобы сделать это.

Сначала попробуйте профилирование задержки. Это полностью внутри процессора, и маловероятно, что люди VTune испортили его слишком сильно.

И, еще раз говорю, вероятность того, что ваша проблема в ядре, а не в L3. Так что VTune должен быть в состоянии справиться с этим.


Попробуйте "Учет циклов" за Левинталь.

Другие вопросы по тегам