Нечетная проблема оптимизации под MSVC

Я видел этот блог:

http://igoro.com/archive/gallery-of-processor-cache-effects/

"Странность" в части 7 - то, что поймало мой интерес.

Моей первой мыслью был "Thats просто C#, являющийся странным".

Не я написал следующий код C++.

volatile int* p = (volatile int*)_aligned_malloc( sizeof( int ) * 8, 64 );
memset( (void*)p, 0, sizeof( int ) * 8 );

double dStart   = t.GetTime();

for (int i = 0; i < 200000000; i++)
{
    //p[0]++;p[1]++;p[2]++;p[3]++;  // Option 1
    //p[0]++;p[2]++;p[4]++;p[6]++;  // Option 2
    p[0]++;p[2]++;                  // Option 3
}

double dTime    = t.GetTime() - dStart;

Синхронизация я вхожу в свой Core 2 Quad на 2,4 ГГц, идет следующим образом:

Option 1 = ~8 cycles per loop.
Option 2 = ~4 cycles per loop.
Option 3 = ~6 cycles per loop.

Теперь Это сбивает с толку. Мое обоснование позади различия сводится к задержке записи кэша (3 цикла) на моей микросхеме и предположении, что кэш имеет 128-разрядный порт записи (Это - чистая работа предположения с моей стороны).

На той основе в Опции 1: Это увеличит p [0] (1 цикл) затем увеличивают p[2] (1 цикл) затем, это должно ожидать 1 цикл (кэша) затем, p[1] (1 цикл) затем ожидает 1 цикл (кэша) затем p[3] (1 цикл). Наконец 2 цикла для инкремента и перехода (Хотя его обычно реализовываемый как декремент и переход). Это дает в общей сложности 8 циклов.

В Опции 2: Это может увеличить p [0], и p[4] в одном цикле затем увеличивают p[2] и p[6] в другом цикле. Затем 2 цикла для вычитают и переходят. Нет ожидает необходимый в кэше. Общие 4 цикла.

В опции 3: Это может увеличить p [0], затем должен ожидать, 2 цикла затем увеличивают p[2], затем вычитают и переходят. Проблема состоит в том при установке случая 3 для постепенного увеличения p [0] и p[4], ВСЕ ЕЩЕ требуется 6 циклов (который вид ударов мой 128-разрядный порт чтения-записи из воды).

Так... кто-либо может сказать мне что, черт возьми, продолжается здесь? Почему ДЕЙСТВИТЕЛЬНО случается 3, занимают больше времени? Также я хотел бы знать то, что я имею неправильно в моих взглядах выше, поскольку у меня, очевидно, есть что-то не так! Любые идеи очень ценились бы!:)

Также было бы интересно видеть, как GCC или любой другой компилятор справляются с ним также!

Править: Идея Jerry Coffin дала мне некоторые мысли.

Я сделал еще некоторые тесты (на другой машине, так простите изменение в синхронизациях) с и без nops и с различными количествами nops

 case 2 - 0.46  00401ABD  jne         (401AB0h)

 0 nops - 0.68  00401AB7  jne         (401AB0h) 
 1 nop  - 0.61  00401AB8  jne         (401AB0h) 
 2 nops - 0.636 00401AB9  jne         (401AB0h) 
 3 nops - 0.632 00401ABA  jne         (401AB0h) 
 4 nops - 0.66  00401ABB  jne         (401AB0h) 
 5 nops - 0.52  00401ABC  jne         (401AB0h) 
 6 nops - 0.46  00401ABD  jne         (401AB0h) 
 7 nops - 0.46  00401ABE  jne         (401AB0h) 
 8 nops - 0.46  00401ABF  jne         (401AB0h)
 9 nops - 0.55  00401AC0  jne         (401AB0h) 

Я включал переход statetements, таким образом, Вы видите, что источник и место назначения находятся в одной строке кэша. Можно также видеть, что мы начинаем получать различие, когда мы - 13 байтов или больше независимо. Пока мы не совершаем нападки 16... затем все это идет не так, как надо.

Таким образом, Jerry не прав (хотя его предложение ДЕЙСТВИТЕЛЬНО помогает немного), однако что-то продолжается. Я все более заинтригован попытаться выяснить то, что это теперь. Это, действительно кажется, больше своего рода причуды выравнивания памяти, а не своего рода причуда пропускной способности инструкции.

Кто-либо хочет объяснить это для любознательного ума?:D

Редактирование 3: у межсойки есть точка на разворачивании, которое уносит предыдущее редактирование из воды. С развернутым циклом не улучшается производительность. Необходимо включить NOP для создания разрыва между источником перехода и местом назначения тем же что касается моего хорошего количества NOP выше. Производительность все еще сосет. Ее интересное, что мне нужны 6 nops для улучшения производительности все же. Интересно, сколько nops процессор может выйти на цикл? Если его 3 затем, которые составляют кэш, пишут задержку... Но, если вот именно, почему задержка происходит?

Curiouser и curiouser...

13
задан Goz 28 March 2011 в 17:47
поделиться

3 ответа

Похоже, это не связано с компилятором. Сначала я подумал, что это может быть из-за уловок компилятора, таких как разворачивание цикла, но, глядя на сгенерированную сборку, MSVC 9.0 просто генерирует прямой перевод из кода C ++.

Вариант 1:

$LL3@main:
    add DWORD PTR [esi], ecx
    add DWORD PTR [esi+4], ecx
    add DWORD PTR [esi+8], ecx
    add DWORD PTR [esi+12], ecx
    sub eax, ecx
    jne SHORT $LL3@main

Вариант 2:

$LL3@main:
    add DWORD PTR [esi], ecx
    add DWORD PTR [esi+8], ecx
    add DWORD PTR [esi+16], ecx
    add DWORD PTR [esi+24], ecx
    sub eax, ecx
    jne SHORT $LL3@main

Вариант 3:

$LL3@main:
    add DWORD PTR [esi], ecx
    add DWORD PTR [esi+8], ecx
    sub eax, ecx
    jne SHORT $LL3@main
2
ответ дан 2 December 2019 в 01:21
поделиться

Набор инструкций x86 больше не является репрезентативным для того, что на самом деле делается центральным процессором. Инструкции переведены на внутренний машинный язык, термин «микрооперация» был придуман еще в 486 дней. Добавьте сюда такие вещи, как переименование регистров, спекулятивное выполнение, несколько исполнительных модулей и их взаимодействие с кешем, и просто невозможно предсказать, сколько времени что-то еще должно занять. Производители микросхем давно перестали публиковать прогнозы времени цикла. Их дизайн - коммерческая тайна.

2
ответ дан 2 December 2019 в 01:21
поделиться

Я сильно подозреваю, что то, что вы видите, - это странность предсказания ветвления, а не что-то связанное с кешированием. В частности, на нескольких процессорах предсказание ветвления не работает (также | вообще), когда и источник, и цель ветвления находятся в одной строке кэша. Помещение достаточного количества кода внутри цикла (даже NOP), чтобы поместить источник и цель в разные строки кэша, даст существенное улучшение скорости.

3
ответ дан 2 December 2019 в 01:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: