shootout fannkuch-redux. Проблема в скорости на X86 -25%
От: SleepyDrago Украина  
Дата: 23.10.10 05:55
Оценка:
Добрый день,
пишу чтобы коллективный разум помог решить проблему большой разницы перформанса между X86 и X64.

Теперь подробнее:
забросил я исходники на плюсах в сабж
Сразу скажу, что ссылку я дал на ту конфигурацию где компилятор мягко говоря не справился — на x64 все намного лучше. К сожалению, пришлось постить 2 программы "наивную" и "оптимизированную" потому что у них там почти все оптимизации переводят в "interesting alternative". С оптимизированной программой проблем нет — всех порвали на тряпки.
Проблема в "наивной" — различие по времени между X64 и X86 слишком большое. Возможно коллективный разум может пояснить в чем проблема и мы отстоим доброе имя с++ ?
Вот сравните
X86 == 76.94 секунды
X64 == 60.14 секунды
Это мягко говоря странно. Я конечно натыкался на то что в гцц каждый бекэнд творит что хочет, но не до такой же степени.
То есть вопрос к залу — как нужно пнуть эту гордую птицу g++ чтобы оно полетело/показало положенные 60 секунд.
Сам давно не запускаю x86 вот и не проверил


ps просто лежал с температурой и пил антибиотики — вот что из этого получилось. Жаль что оптимизированную программу не приняли в основной забег. Там приведены цифры на процессоре без sse4.1 — с ним оно еще на 10% быстрее. Первый submission у них просто выдал Illegal instruction и упал Пришлось делать аккуратнее: с возможностью без sse4 только на ssse3.
Re: shootout fannkuch-redux. Проблема в скорости на X86 -25%
От: Тот кто сидит в пруду Россия  
Дата: 23.10.10 19:48
Оценка:
Здравствуйте, SleepyDrago, Вы писали:

SD>Добрый день,

SD> пишу чтобы коллективный разум помог решить проблему большой разницы перформанса между X86 и X64.

SD>Теперь подробнее:

SD> забросил я исходники на плюсах в сабж
SD> Сразу скажу, что ссылку я дал на ту конфигурацию где компилятор мягко говоря не справился — на x64 все намного лучше. К сожалению, пришлось постить 2 программы "наивную" и "оптимизированную" потому что у них там почти все оптимизации переводят в "interesting alternative". С оптимизированной программой проблем нет — всех порвали на тряпки.
SD> Проблема в "наивной" — различие по времени между X64 и X86 слишком большое. Возможно коллективный разум может пояснить в чем проблема и мы отстоим доброе имя с++ ?
SD> Вот сравните
SD>X86 == 76.94 секунды
SD>X64 == 60.14 секунды
SD>Это мягко говоря странно. Я конечно натыкался на то что в гцц каждый бекэнд творит что хочет, но не до такой же степени.
SD> То есть вопрос к залу — как нужно пнуть эту гордую птицу g++ чтобы оно полетело/показало положенные 60 секунд.
SD>Сам давно не запускаю x86 вот и не проверил
SD>

SD>ps просто лежал с температурой и пил антибиотики — вот что из этого получилось. Жаль что оптимизированную программу не приняли в основной забег. Там приведены цифры на процессоре без sse4.1 — с ним оно еще на 10% быстрее. Первый submission у них просто выдал Illegal instruction и упал Пришлось делать аккуратнее: с возможностью без sse4 только на ssse3.


Разница и должна быть, у x64 регистров намного больше.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re: shootout fannkuch-redux. Проблема в скорости на X86 -25%
От: Тот кто сидит в пруду Россия  
Дата: 23.10.10 20:25
Оценка:
Здравствуйте, SleepyDrago, Вы писали:

SD>Теперь подробнее:

SD> забросил я исходники на плюсах в сабж
SD> Сразу скажу, что ссылку я дал на ту конфигурацию где компилятор мягко говоря не справился — на x64 все намного лучше. К сожалению, пришлось постить 2 программы "наивную" и "оптимизированную" потому что у них там почти все оптимизации переводят в "interesting alternative". С оптимизированной программой проблем нет — всех порвали на тряпки.
SD> Проблема в "наивной" — различие по времени между X64 и X86 слишком большое. Возможно коллективный разум может пояснить в чем проблема и мы отстоим доброе имя с++ ?

Глянул на код — такое впечатление, что программу специально пытались замедлить. Может, я, конечно, и не въехал за 5 минут, и там на самом деле были какие-то разумные соображения, но нафига там куча лишних копирований? И вообще пошто туман из кастов на ровном месте нагоняют?
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re: offtop
От: rg45 СССР  
Дата: 24.10.10 08:15
Оценка: 9 (1)
Здравствуйте, SleepyDrago, Вы писали:

SD>...


Случайно упал взгляд на это:
P assign(const char d[16])
{
//...
}

Согласно 8.3.5/3 параметры-массивы автоматически преобразуются компилятором в параметры указатели:

...After determining thetype of each parameter, any parameter of type “array of T” or “function returning T” is adjusted to be “pointer to T” or pointer to function returning T,” respectively...

Т.е. в данном случае параметр d — это вовсе не массив, несмотря на то, что объявлен он как массив, а обычный указатель. Т.о. в такую функцию в качестве фактических параметров можно передавать обычные указатели, и, что еще хуже, массивы других размеров. Поэтому чтобы не вводить в заблуждение, параметр d лучше честно объявить как указатель, а еще лучше — как ссылку на массив размера 16:
P assign(const char (&d)[16])
{
//...
}
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[2]: shootout fannkuch-redux. Проблема в скорости на X86 -
От: SleepyDrago Украина  
Дата: 24.10.10 09:42
Оценка:
Здравствуйте, Тот кто сидит в пруду, Вы писали:

ТКС>Здравствуйте, SleepyDrago, Вы писали:


SD>>Добрый день,

SD>> пишу чтобы коллективный разум помог решить проблему большой разницы перформанса между X86 и X64.

ТКС>Разница и должна быть, у x64 регистров намного больше.


Это не тот случай. Единственное место где скорость имеет значение

P& reverse(P& p, int n)
{
    for ( int lo = 0, hi = n ; lo < hi; ++lo, --hi ) 
    {
        swap( access(p, lo), access( p, hi) );
    }
    return p;
}

этот цикл разворачивается в ~6 инструкций и использует 3 регистра — их вполне достаточно.
Re[2]: shootout fannkuch-redux. Проблема в скорости на X86 -
От: SleepyDrago Украина  
Дата: 24.10.10 10:14
Оценка:
Здравствуйте, Тот кто сидит в пруду, Вы писали:

ТКС>Здравствуйте, SleepyDrago, Вы писали:

...
SD>> Проблема в "наивной" — различие по времени между X64 и X86 слишком большое. Возможно коллективный разум может пояснить в чем проблема и мы отстоим доброе имя с++ ?

ТКС>Глянул на код — такое впечатление, что программу специально пытались замедлить. Может, я, конечно, и не въехал за 5 минут, и там на самом деле были какие-то разумные соображения, но нафига там куча лишних копирований? И вообще пошто туман из кастов на ровном месте нагоняют?


Я пытался пояснить что я написал оптимизированную программу, которая обгоняет все что там было больше чем в 2 раза за счет использования SSE4.1 Пока я ее писал устроители бенчмарка решили запретить оптимизации так как они не вписываются в цель сравнения языков. По ходу выяснилось что их машинка не держит sse4 и пришлось писать именно такую функцию access с той лишь разницей что в оптимизированной P передавалось по значению. Походу они меня убедили послать и отладочную версию на "просто С++". Я послал им одну программу которая отличалась десятком строк и была одновременно и оптимизированной и наивной по #define. Поскольку они меряют и количество строк кода — они попросили меня разделить их на 2.
Вот так получилось то что получилось.
Я померял на X64 и увидел что результат вполне достаточен для первых мест (~60 секунд). Поскольку я по работе давно не пользуюсь X86 я просто и не запускал что там получилось.
Сейчас я поставил себе X86 и вижу в чем проблема...

Так вот смех и грех в том, что если убрать функцию access то на X86 все выравнивается а на X64 кодогенератор начинает тупить
С точки зрения того что я знаю про с++ эти 2 функции эквивалентны при инлайнинге и вычисляют один и тот же адрес элемента массива.
char& access(P & p, int i) 
{
    return p.data[i];
}
char& access(P & p, int i) 
{
    return reinterpret_cast<char*>(&p)[i];
}

Ни профайлер (на win32) ни ассемблерный листинг на линуксе копирований в программе в упор не видят так что это ложный след.
Вся разница в скорости в коде цикла в reverse
причем после "упрощения" X64 там генерируется цикл по другому и время замедляется на 8 секунд — 60 -> 68.
Вот такие вот пирожки с котятами.
Re[2]: offtop
От: SleepyDrago Украина  
Дата: 24.10.10 10:32
Оценка: 1 (1)
Здравствуйте, rg45, Вы писали:

R>Здравствуйте, SleepyDrago, Вы писали:


SD>>...


R>Случайно упал взгляд на это:

R>
R>P assign(const char d[16])
R>{
R>//...
R>}
R>

R>Согласно 8.3.5/3 параметры-массивы автоматически преобразуются компилятором в параметры указатели:
Смысл этой функции скопировать ровно 16 байт один раз в начале программы. Разумеется ее можно написать лучше, когда я ее писал меня интересовала скорость работы, а как ты знаешь с этой точки зрения между указателем и ссылкой разницу обнаружить не удастся. Тем более что программу такого размера приходится рассматривать в дизассемблере целиком так как все функции схлопываются и в асме остается только тело std::copy
Вся эта функция нужна была в оптимизированной программе, чтобы загнать значение из массива символов в регистр процессора (xmm). Иначе я бы ее не стал писать.
Возможно я отправлю исправление им специально для этой программки и уберу все что в ней не особо нужно, но за этой мишурой кроется реальная проблема в кодогенераторе gcc4.4 вот на этот счет меня и интересует твое мнение.
То есть есть функция reverse которая переставляет заданное количество байт в обратном порядке в цикле. Код на одной платформе генерируется нормально (60 секунд) на другой криво (76 секунд). Предсказать такое я не мог.
Забавно что если "потрогать" функцию access и написать ее вот так:
char& access(P & p, int i) 
{
    return p.data[i];
}

вместо
char& access(P & p, int i) 
{
    return reinterpret_cast<char*>(&p)[i];
}


То картина меняется на противоположную — X86 все хорошо ( 5х секунд) а на X64 резко хуже — 68 секунд вместо 60.
Все что я знаю про этот язык говорит что этого не может быть. Но игнорировать факты бесполезно.
Re[3]: shootout fannkuch-redux. Проблема в скорости на X86 -
От: jazzer Россия Skype: enerjazzer
Дата: 24.10.10 11:07
Оценка:
Здравствуйте, SleepyDrago, Вы писали:

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

Идиоты
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[4]: shootout fannkuch-redux. Проблема в скорости на X86 -
От: SleepyDrago Украина  
Дата: 24.10.10 13:00
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Здравствуйте, SleepyDrago, Вы писали:


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

J>Идиоты

Вообще-то я написал сюда потому что я в шоке от того что вытворяет gcc4.4
Мы пока сидим на 4.1.2 (редхат) но системы на базе 4.4 уже стучатся в дверь.

Пока что картина маслом такая — либо x86 либо x64 на наивном коде функции "развернуть массив байт(массив, длина)" генерируют УГ которое на 10-20% отличается в минус от него же самого "в хорошем настроении". Я молчу что оно же отстает от msvc2010 — мне важно понять или это лыжи не едут или я ...

могу сюда или на шутаут выложить 2 программки по 200 строк которые феерически по разному тормозят на x86 vs x64.
Подумываю написать в рассылку гнуцц (надо собраться с силами и вспомнить цензурный английский)

для шутаута не важно — а вот с переходом на работе я начинаю серьезно сомневаться.
Re[5]: shootout fannkuch-redux. Проблема в скорости на X86 -
От: jazzer Россия Skype: enerjazzer
Дата: 24.10.10 13:26
Оценка:
Здравствуйте, SleepyDrago, Вы писали:

SD>Вообще-то я написал сюда потому что я в шоке от того что вытворяет gcc4.4

SD>Мы пока сидим на 4.1.2 (редхат) но системы на базе 4.4 уже стучатся в дверь.
Странно, вроде, 4.1 — это самый плохой гнутый компилятор с точки зрения скорости считается, куда уж хуже...

SD>Пока что картина маслом такая — либо x86 либо x64 на наивном коде функции "развернуть массив байт(массив, длина)" генерируют УГ которое на 10-20% отличается в минус от него же самого "в хорошем настроении". Я молчу что оно же отстает от msvc2010 — мне важно понять или это лыжи не едут или я ...

А можно тезисно, в чем дело, что меняется? (меня толкьо 64 интересует)

SD>могу сюда или на шутаут выложить 2 программки по 200 строк которые феерически по разному тормозят на x86 vs x64.

лучше сюда

SD> Подумываю написать в рассылку гнуцц (надо собраться с силами и вспомнить цензурный английский)

Напиши, конечно!

SD>для шутаута не важно — а вот с переходом на работе я начинаю серьезно сомневаться.

Да, мы тоже планируем, я как раз с ним бьюсь, несколько багов редхат уже пофиксил.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[3]: shootout fannkuch-redux. Проблема в скорости на X86 -
От: Тот кто сидит в пруду Россия  
Дата: 25.10.10 07:02
Оценка:
Здравствуйте, SleepyDrago, Вы писали:

SD>>>Добрый день,

SD>>> пишу чтобы коллективный разум помог решить проблему большой разницы перформанса между X86 и X64.

ТКС>>Разница и должна быть, у x64 регистров намного больше.


SD>Это не тот случай. Единственное место где скорость имеет значение


SD>
SD>P& reverse(P& p, int n)
SD>{
SD>    for ( int lo = 0, hi = n ; lo < hi; ++lo, --hi ) 
SD>    {
SD>        swap( access(p, lo), access( p, hi) );
SD>    }
SD>    return p;
SD>}
SD>

SD>этот цикл разворачивается в ~6 инструкций и использует 3 регистра — их вполне достаточно.

Что значит "хватает"? Регистров просто мало, вот он тремя и обходится.
MSVC цикл в count_flips превращает в следующее:

.text:0000000140001C20                 inc     r11d
.text:0000000140001C23                 xor     r8d, r8d
.text:0000000140001C26                 movsxd  r9, eax
.text:0000000140001C29                 test    eax, eax
.text:0000000140001C2B                 jle     short loc_140001C58
.text:0000000140001C2D                 lea     rdx, [rsp+r9+28h+var_28]
.text:0000000140001C31
.text:0000000140001C31 loc_140001C31:                          ; CODE XREF: Fannkuchredux::count_flips(Fannkuchredux::R &,int)+72j
.text:0000000140001C31                 lea     r10, [rsp+r8+28h+var_28]
.text:0000000140001C35                 cmp     r10, rdx
.text:0000000140001C38                 jz      short loc_140001C46
.text:0000000140001C3A                 movzx   eax, byte ptr [rdx]
.text:0000000140001C3D                 movzx   ecx, byte ptr [r10]
.text:0000000140001C41                 mov     [r10], al
.text:0000000140001C44                 mov     [rdx], cl
.text:0000000140001C46
.text:0000000140001C46 loc_140001C46:                          ; CODE XREF: Fannkuchredux::count_flips(Fannkuchredux::R &,int)+58j
.text:0000000140001C46                 inc     r8
.text:0000000140001C49                 dec     r9
.text:0000000140001C4C                 dec     rdx
.text:0000000140001C4F                 cmp     r8, r9
.text:0000000140001C52                 jl      short loc_140001C31
.text:0000000140001C54                 movzx   ecx, [rsp+28h+var_28]
.text:0000000140001C58
.text:0000000140001C58 loc_140001C58:                          ; CODE XREF: Fannkuchredux::count_flips(Fannkuchredux::R &,int)+4Bj
.text:0000000140001C58                 movsx   eax, cl
.text:0000000140001C5B                 test    cl, cl
.text:0000000140001C5D                 jnz     short loc_140001C20


Как не трудно посчитать, используются 7 регистров общего назначения.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[4]: shootout fannkuch-redux. Проблема в скорости на X86 -
От: SleepyDrago Украина  
Дата: 25.10.10 07:36
Оценка:
Здравствуйте, Тот кто сидит в пруду, Вы писали:

ТКС>Здравствуйте, SleepyDrago, Вы писали:


SD>>>>Добрый день,

SD>>>> пишу чтобы коллективный разум помог решить проблему большой разницы перформанса между X86 и X64.

ТКС>>>Разница и должна быть, у x64 регистров намного больше.


SD>>Это не тот случай. Единственное место где скорость имеет значение


SD>>
SD>>P& reverse(P& p, int n)
SD>>{
SD>>    for ( int lo = 0, hi = n ; lo < hi; ++lo, --hi ) 
SD>>    {
SD>>        swap( access(p, lo), access( p, hi) );
SD>>    }
SD>>    return p;
SD>>}
SD>>

SD>>этот цикл разворачивается в ~6 инструкций и использует 3 регистра — их вполне достаточно.

ТКС>Что значит "хватает"? Регистров просто мало, вот он тремя и обходится.

ТКС>MSVC цикл в count_flips превращает в следующее:

ТКС>
ТКС>.text:0000000140001C20                 inc     r11d
ТКС>.text:0000000140001C23                 xor     r8d, r8d
ТКС>.text:0000000140001C26                 movsxd  r9, eax
ТКС>.text:0000000140001C29                 test    eax, eax
ТКС>.text:0000000140001C2B                 jle     short loc_140001C58
ТКС>.text:0000000140001C2D                 lea     rdx, [rsp+r9+28h+var_28]
ТКС>.text:0000000140001C31
ТКС>.text:0000000140001C31 loc_140001C31:                          ; CODE XREF: Fannkuchredux::count_flips(Fannkuchredux::R &,int)+72j
ТКС>.text:0000000140001C31                 lea     r10, [rsp+r8+28h+var_28]
ТКС>.text:0000000140001C35                 cmp     r10, rdx
ТКС>.text:0000000140001C38                 jz      short loc_140001C46
ТКС>.text:0000000140001C3A                 movzx   eax, byte ptr [rdx]
ТКС>.text:0000000140001C3D                 movzx   ecx, byte ptr [r10]
ТКС>.text:0000000140001C41                 mov     [r10], al
ТКС>.text:0000000140001C44                 mov     [rdx], cl
ТКС>.text:0000000140001C46
ТКС>.text:0000000140001C46 loc_140001C46:                          ; CODE XREF: Fannkuchredux::count_flips(Fannkuchredux::R &,int)+58j
ТКС>.text:0000000140001C46                 inc     r8
ТКС>.text:0000000140001C49                 dec     r9
ТКС>.text:0000000140001C4C                 dec     rdx
ТКС>.text:0000000140001C4F                 cmp     r8, r9
ТКС>.text:0000000140001C52                 jl      short loc_140001C31
ТКС>.text:0000000140001C54                 movzx   ecx, [rsp+28h+var_28]
ТКС>.text:0000000140001C58
ТКС>.text:0000000140001C58 loc_140001C58:                          ; CODE XREF: Fannkuchredux::count_flips(Fannkuchredux::R &,int)+4Bj
ТКС>.text:0000000140001C58                 movsx   eax, cl
ТКС>.text:0000000140001C5B                 test    cl, cl
ТКС>.text:0000000140001C5D                 jnz     short loc_140001C20
ТКС>


ТКС>Как не трудно посчитать, используются 7 регистров общего назначения.

На счет числа регистров я не прав — я забыл посчитать те что используются в адресации их 7.
Но есть пара нюансов.
*)Сборка с g++-4.5 на ubuntu 10.10x86 работает нормально ( еще быстрее чем опубликованная x64 ).
*)та же программа на 10.4х86 с тривиально измененной функцией access работает нормально.
Так что при простом подсчете дело не в количестве регистров и 7 для х86 не проблема.

щас попробую отписать ниже в теме все эксперименты которые я провел — может станет более понятно.
Re[6]: shootout fannkuch-redux. Проблема в скорости на X86 -
От: SleepyDrago Украина  
Дата: 25.10.10 08:08
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Здравствуйте, SleepyDrago, Вы писали:


SD>>Пока что картина маслом такая — либо x86 либо x64 на наивном коде функции "развернуть массив байт(массив, длина)" генерируют УГ которое на 10-20% отличается в минус от него же самого "в хорошем настроении". Я молчу что оно же отстает от msvc2010 — мне важно понять или это лыжи не едут или я ...

J>А можно тезисно, в чем дело, что меняется? (меня только 64 интересует)

итак программа есть там Уменьшить ее не удалось.

она собирается на ubuntu10.4 компилятором g++ 4.4 с пакетом libboost-thread-dev, ключи внизу страницы. Для проверки того что показывает проще всего коротнуть условие чтобы не вызывалась многопоточность и дать в командной строке аргумент "11".

Причины почему она специально написана так я попытался описать выше по теме (организаторы шутят, остатки совместимости с оптимизированной программой )

В ней >90% времени занимает один хотспот — тушка заинлайненой функции reverse лежащая прямо в main. Imho При такой кривизне программы эффекты 2го порядка малости дают +-25% к общему времени. Вопрос какие и как помочь g++ в поисках минимума.

Под тормозами я понимаю >+20% времени исполнения. Ниже эксперименты которые я провел:

* сборка в ubuntu10.10x64 с тем пакетом буста (1.42) что там — тормоза. Устанавливаем 1.40 из репо и собираем — тормоза. Для проверки sanity копируем с 10.4 бинарник с установленным 1.40 он запускается и работает нормально. Ассемблерный листинг reverse структурных отличий не содержит (!).

* сборка без буста и потоков (тупо удаляем инклюд и вызовы и из линковки) на 10.4 — тормоза в той же среде (!).

* меняем access на
char& access(P & p, int i) 
{
    return p.data[i];
}

и тормоза. Поскольку цикл сгенерировался иначе невозможно определить что виновно больше команды или смещение.

Первое подозрение на то что g++ случайно угадал размещение цикла по нужному смещению которое любят Core2Quad'ы.
Пока ни одно из сочетаний "-falign-*=N" мне не помогло

Интересуют любые предположения тк мы имеем какой то локальный экстремум который скорее всего сломается после серьезного обновления на тестовой машине.

Потенциально эта программа способна без изменений исполняться еще на 10% быстрее на том же железе — доказано с помощью ubuntu10.10x86 && g++-4.5
В общем я пока не понимаю что происходит.

ps. засим вынужден на время от этого удалиться тк было время пока я недельку валялся пил антибиотики — пришло время обратно в окоп.
Re[7]: shootout fannkuch-redux. Проблема в скорости на X86 -
От: SleepyDrago Украина  
Дата: 26.10.10 09:54
Оценка:
Здравствуйте, SleepyDrago, Вы писали:

обновление по результатам вчерашнего разглядывания выхлопа objdump
...
SD>* сборка в ubuntu10.10x64 с тем пакетом буста (1.42) что там — тормоза. Устанавливаем 1.40 из репо и собираем — тормоза. Для проверки sanity копируем с 10.4 бинарник с установленным 1.40 он запускается и работает нормально. Ассемблерный листинг reverse структурных отличий не содержит (!).
смотрел в objdump'е цикл отличается по размеру — на 1 байт больше.

Выравнивание отпало тк все отсмотренные листинги показали что начало цикла выровнено. (кроме 4.4x86 но ему и выравнивание не помогает)

текущая рабочая гипотеза — чем меньше байт (групп по 16) занимает тело цикла тем лучше. Пока она примерно коррелирует с измерениями. 2 лидера g++-4.5x86 и MSVC2010x86 Причем у мс цикл еще меньше но время немного больше. Затем идет g++4.4x64 (тот что считаем ок) и отстающие: на 1 байт больше ( 43 ) g++4.4x64_ubuntu10.10 с существенным замедлением. Самый жирный код получился у g++4.4x86 он и замыкает список участников.

Практический вопрос — как программист может пнуть g++ чтобы он понял чтото в заданном локальном фрагменте. Запись цикла асмом увы не подходит по условию конкурса.
Re[6]: shootout fannkuch-redux. Проблема в скорости на X86 -
От: SleepyDrago Украина  
Дата: 26.10.10 16:08
Оценка:
Здравствуйте, jazzer, Вы писали:

SD>>Вообще-то я написал сюда потому что я в шоке от того что вытворяет gcc4.4

SD>>Мы пока сидим на 4.1.2 (редхат) но системы на базе 4.4 уже стучатся в дверь.
J>Странно, вроде, 4.1 — это самый плохой гнутый компилятор с точки зрения скорости считается, куда уж хуже...

дошли руки запустить на 4.1.2 редхате x64 == 50 секунд на Q9300 2.5 GHz. При лучшем результате 4.4 в 60 секунд. на аналогичном железе 4.4 сливает в чистую.

Причем все упирается в генерацию цикла из 6 команд.

И еще — на сайте когда я начал просить 4.5 сделали обновление на 4.4.4 и результат сполз на 6е место (71 секунд на Q6600 2.4 GHz).
Re[3]: shootout fannkuch-redux. Проблема в скорости на X86 -
От: minorlogic Украина  
Дата: 27.10.10 05:29
Оценка:
Здравствуйте, SleepyDrago, Вы писали:



SD>Это не тот случай. Единственное место где скорость имеет значение


SD>
SD>P& reverse(P& p, int n)
SD>{
SD>    for ( int lo = 0, hi = n ; lo < hi; ++lo, --hi ) 
SD>    {
SD>        swap( access(p, lo), access( p, hi) );
SD>    }
SD>    return p;
SD>}
SD>

SD>этот цикл разворачивается в ~6 инструкций и использует 3 регистра — их вполне достаточно.

а пробовали std::reverse ? зачем тут дополнительная адресация через p а не напрямую к data?
... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
Ищу работу, 3D, SLAM, computer graphics/vision.
Re[4]: shootout fannkuch-redux. Проблема в скорости на X86 -
От: SleepyDrago Украина  
Дата: 27.10.10 10:48
Оценка:
Здравствуйте, minorlogic, Вы писали:

M>Здравствуйте, SleepyDrago, Вы писали:




SD>>Это не тот случай. Единственное место где скорость имеет значение


SD>>
SD>>P& reverse(P& p, int n)
SD>>{
SD>>    for ( int lo = 0, hi = n ; lo < hi; ++lo, --hi ) 
SD>>    {
SD>>        swap( access(p, lo), access( p, hi) );
SD>>    }
SD>>    return p;
SD>>}
SD>>

SD>>этот цикл разворачивается в ~6 инструкций и использует 3 регистра — их вполне достаточно.

M> а пробовали std::reverse ? зачем тут дополнительная адресация через p а не напрямую к data?


чего только не пробовал и objdump'ил и результаты сличал.

Результат моих приключений. g++4.4 (обе платформы) g++4.5(x64) на этом коде выступают с позорным 6м местом.
g++4.1.2(x64 — другой не смотрел) — отлично (1е с запасом), g++4.5 (x86) — нормально ( на уровне первого места)
Причем в начале g++4.4 x64 случайно показал терпимый результат и поэтому я выложил. После минорного обновления на днях время изменилось с 60 секунд до 71 секунды ( 4.4.3 -> 4.4.4 ).

Задачку как убедить g++ решил вчера вечером — на выходных опубликую В качестве превью скажу что на исправленном цикле 4.1.2x64 показывает время меньше 50 Остальное можно не трогать. Выложу с учетом жалоб наших форумных эстетов чтобы было почище и покомпактнее.

общий вывод не доводить до таких хотспотов и не переходить на g++4.4 пока в силе. По мере того как появятся примеры где g++4.4 лучше второй будет пересматриваться. Первый здесь вынужден организаторами забега.
Re[5]: shootout fannkuch-redux. Проблема в скорости на X86 -
От: minorlogic Украина  
Дата: 27.10.10 17:09
Оценка:
Здравствуйте, SleepyDrago, Вы писали:

SD>Здравствуйте, minorlogic, Вы писали:


M>>Здравствуйте, SleepyDrago, Вы писали:




SD>>>Это не тот случай. Единственное место где скорость имеет значение


SD>>>
SD>>>P& reverse(P& p, int n)
SD>>>{
SD>>>    for ( int lo = 0, hi = n ; lo < hi; ++lo, --hi ) 
SD>>>    {
SD>>>        swap( access(p, lo), access( p, hi) );
SD>>>    }
SD>>>    return p;
SD>>>}
SD>>>

SD>>>этот цикл разворачивается в ~6 инструкций и использует 3 регистра — их вполне достаточно.

M>> а пробовали std::reverse ? зачем тут дополнительная адресация через p а не напрямую к data?


SD>чего только не пробовал и objdump'ил и результаты сличал.


Очень странно , std::reverse по идее должен оптимальный код с итераторами генерить.

Посмотрим что там дальше Кстати если это критический кусок то можно свопить сразу блоками через дополнительную память, должно быть более кеш френдли.

И если я правильно понял программу то объектв которые свопятся это P16{ char data[16];} ? тогда конечно стоит свопить не данные а индексы к данным.
... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
Ищу работу, 3D, SLAM, computer graphics/vision.
Re[6]: shootout fannkuch-redux. Проблема в скорости на X86 -
От: SleepyDrago Украина  
Дата: 28.10.10 08:43
Оценка:
Здравствуйте, minorlogic, Вы писали:

M>Здравствуйте, SleepyDrago, Вы писали:


SD>>Здравствуйте, minorlogic, Вы писали:


M>>>Здравствуйте, SleepyDrago, Вы писали:




SD>>>>Это не тот случай. Единственное место где скорость имеет значение


SD>>>>
SD>>>>P& reverse(P& p, int n)
SD>>>>{
SD>>>>    for ( int lo = 0, hi = n ; lo < hi; ++lo, --hi ) 
SD>>>>    {
SD>>>>        swap( access(p, lo), access( p, hi) );
SD>>>>    }
SD>>>>    return p;
SD>>>>}
SD>>>>

SD>>>>этот цикл разворачивается в ~6 инструкций и использует 3 регистра — их вполне достаточно.

M>>> а пробовали std::reverse ? зачем тут дополнительная адресация через p а не напрямую к data?


SD>>чего только не пробовал и objdump'ил и результаты сличал.


M>Очень странно , std::reverse по идее должен оптимальный код с итераторами генерить.


M>Посмотрим что там дальше Кстати если это критический кусок то можно свопить сразу блоками через дополнительную память, должно быть более кеш френдли.


M>И если я правильно понял программу то объектв которые свопятся это P16{ char data[16];} ? тогда конечно стоит свопить не данные а индексы к данным.


нет оно выполняет reverse части перестановки в цикле. переставляются байты.
вот опубликован фикс на проблемы кодогена — там комментарий в интересном месте на 2 строки )

зато вылезли проблемы с потоками но тут надо звать помощь тк у меня инструментов для диагностики считай нет. Выглядит это весело — на x86 через раз работает в 2 раза медленнее а на x64 это проявляется в резкой разбалансировке нагрузки (cpu 53.76 elapsed 15.68)
Re[7]: shootout fannkuch-redux. Проблема в скорости на X86 -
От: minorlogic Украина  
Дата: 28.10.10 12:32
Оценка:
Здравствуйте, SleepyDrago, Вы писали:

SD>нет оно выполняет reverse части перестановки в цикле. переставляются байты.

SD>вот опубликован фикс на проблемы кодогена — там комментарий в интересном месте на 2 строки )


void reverse(int n)
{
        // following lines are very carefully written to meet both test 
        // conditions and reasonable timings. 
        char * lo = &data[0], * hi = &data[n];
        for (; lo < hi; ++lo, --hi) 
            swap( *lo, *hi );
}


Выглядит exactly как std::reverseю А своп по правилам можно через XOR например ?
Ищу работу, 3D, SLAM, computer graphics/vision.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.