Re[8]: [Nemerle] Codegen quality
От: rameel https://github.com/rsdn/CodeJam
Дата: 02.03.17 20:38
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Ты какую ветку Нитры собираешь?


master
... << RSDN@Home 1.0.0 alpha 5 rev. 0>>
Re[9]: [Nemerle] Codegen quality
От: VladD2 Российская Империя www.nemerle.org
Дата: 02.03.17 20:49
Оценка:
Здравствуйте, rameel, Вы писали:

R>master


А грамматика шарпа у тебя там собралась?

В общем, попробуй мою ветку собрать.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[10]: [Nemerle] Codegen quality
От: rameel https://github.com/rsdn/CodeJam
Дата: 02.03.17 21:08
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>А грамматика шарпа у тебя там собралась?


Я не так делал, я кликнул по BuildBoot.cmd А так да, ошибки валятся: ExtensibleRuleParseTreeConstructor.n(66,17): error : goto (block return?) is not allowed inside expressions
... << RSDN@Home 1.0.0 alpha 5 rev. 0>>
Re[11]: [Nemerle] Codegen quality
От: VladD2 Российская Империя www.nemerle.org
Дата: 02.03.17 21:12
Оценка:
Здравствуйте, rameel, Вы писали:

R>Я не так делал, я кликнул по BuildBoot.cmd А так да, ошибки валятся: ExtensibleRuleParseTreeConstructor.n(66,17): error : goto (block return?) is not allowed inside expressions


Ну, вот и у меня это вылезло. Надо разбираться что там и как. Вопрос имеет ли в этом смысл? Я правильно понял, что использование ldlen достаточно?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: [Nemerle] Codegen quality
От: VladD2 Российская Империя www.nemerle.org
Дата: 02.03.17 21:13
Оценка:
Здравствуйте, rameel, Вы писали:

R>Как побороть ошибку FSM\DFSMTransform.n(198,9,229,10): error : Label 'Next' (12583) multiply defined ? Пытался по всякому, не работает.


Исправил это дело в v1.2.532.0.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: [Nemerle] Codegen quality
От: VladD2 Российская Империя www.nemerle.org
Дата: 02.03.17 21:35
Оценка:
Здравствуйте, rameel, Вы писали:

R>Результы изменений: джит полностью устранил проверку выхода за границу массива, проверку на null и вызов чего-то там на каждой итерации цикла

R>
R>Before:  1605 ms,  ips:    622 993,61
R> After:   329 ms,  ips:  3 031 065,39
R>


Я правильно понял, что это за счет замены вызова геттара на ldlen?

Если да, то интересно сравнение с аналогичным кодом на Шарпе.

И покажи что за асм там получился, плиз.

R>5 кратное ускорение на простом цикле


Ну, это потому что цикл почти пустой. Интересно попробовать оценить разницу на той же Нитре. Мы там сурово с массивами работаем.

Откровенно говоря мне раньше даже в голову не приходило, что там оптимизация не делается, и что надо ldlen вместо get_Length использовать.

R>Кстати, перед тем как отправить пуллреквест, хочу спросить. Я в методе emit_method_call добавил такое условие:

R>
R>      else if (method.DeclaringType == typeof(Array) && method.Name == "get_Length")
R>      {
R>        _ilg.Emit(OpCodes.Ldlen);
R>        _ilg.Emit(OpCodes.Conv_I4);
R>      }
R>


R>Так в проекте делается или надо каким-то образом немерлевские метаданные проверять?


Можно и немерловыми, но насколько это нужно я не знаю. Надо смотреть что за код рядом находится.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[12]: [Nemerle] Codegen quality
От: rameel https://github.com/rsdn/CodeJam
Дата: 02.03.17 22:05
Оценка:
Здравствуйте, VladD2, Вы писали:

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


R>>А так да, ошибки валятся: ExtensibleRuleParseTreeConstructor.n(66,17): error : goto (block return?) is not allowed inside expressions


VD>Ну, вот и у меня это вылезло. Надо разбираться что там и как.


Глядя на то, во что раскрылся макрос, то ничего криминального не вижу

VD>Вопрос имеет ли в этом смысл? Я правильно понял, что использование ldlen достаточно?


Думаю да, можно еще что-нибудь поискать
... << RSDN@Home 1.0.0 alpha 5 rev. 0>>
Re[3]: [Nemerle] Codegen quality
От: rameel https://github.com/rsdn/CodeJam
Дата: 02.03.17 22:05
Оценка:
Здравствуйте, VladD2, Вы писали:

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


R>>Результы изменений: джит полностью устранил проверку выхода за границу массива, проверку на null и вызов чего-то там на каждой итерации цикла


VD>Я правильно понял, что это за счет замены вызова геттара на ldlen?


Ага

VD>Если да, то интересно сравнение с аналогичным кодом на Шарпе.


На шарпе чуть быстрее, но не принципиально, и то это потому что тело цикла тривиальное

nemerle: 329 ms, ips: 3 031 065,39
charp  : 308 ms, ips: 3 238 606,26


VD>И покажи что за асм там получился, плиз.


Для шарпа
00007FFBEBEC0CE5  xor         r8d,r8d  

00007FFBEBEC0CE8  mov         r9d,dword ptr [rax+8]  
00007FFBEBEC0CEC  test        r9d,r9d  
00007FFBEBEC0CEF  jle         00007FFBEBEC0D04  

00007FFBEBEC0CF1  movsxd      r10,r8d  
00007FFBEBEC0CF4  mov         r10d,dword ptr [rax+r10*4+10h]  
00007FFBEBEC0CF9  add         ecx,r10d  
00007FFBEBEC0CFC  inc         r8d  
00007FFBEBEC0CFF  cmp         r9d,r8d  
00007FFBEBEC0D02  jg          00007FFBEBEC0CF1


Для немерле:
00007FFBEBED0BE5  xor         eax,eax  
00007FFBEBED0BE7  mov         edx,dword ptr [rsi+8]  

00007FFBEBED0BEA  cmp         edx,eax  
00007FFBEBED0BEC  jle         00007FFBEBED0BFB  
00007FFBEBED0BEE  movsxd      rcx,eax  
00007FFBEBED0BF1  mov         ecx,dword ptr [rsi+rcx*4+10h]  
00007FFBEBED0BF5  add         edi,ecx  
00007FFBEBED0BF7  inc         eax  
00007FFBEBED0BF9  jmp         00007FFBEBED0BEA
... << RSDN@Home 1.0.0 alpha 5 rev. 0>>
Re[3]: [Nemerle] Codegen quality
От: rameel https://github.com/rsdn/CodeJam
Дата: 02.03.17 22:23
Оценка:
Здравствуйте, VladD2, Вы писали:

Отправил пулл реквест
... << RSDN@Home 1.0.0 alpha 5 rev. 0>>
Re[13]: [Nemerle] Codegen quality
От: VladD2 Российская Империя www.nemerle.org
Дата: 02.03.17 23:07
Оценка:
Здравствуйте, rameel, Вы писали:

R>Глядя на то, во что раскрылся макрос, то ничего криминального не вижу Image: GotoMacroError.png


Это надо под отладчиком разбираться (долго и нудно). Может просто проверки не очень умные. А может все же есть что-то что так не видно.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[11]: [Nemerle] Codegen quality
От: VladD2 Российская Империя www.nemerle.org
Дата: 02.03.17 23:17
Оценка:
Здравствуйте, rameel, Вы писали:

R>Я не так делал, я кликнул по BuildBoot.cmd А так да, ошибки валятся: ExtensibleRuleParseTreeConstructor.n(66,17): error : goto (block return?) is not allowed inside expressions


В коде есть комент:
// try prevent error: goto (block return?) is not allowed inside expressions

Так что похоже это какая-то древняя проблема.

В общем, чтобы с этим разбираться сначала надо выявить минимальный пример воспроизводящий проблему и уже потом смотреть, что там не так. Это довольно муторно. Возможно косяки с расчетом Context.AllowGoto. А может что-то связанное с отладочной информацией, как в случае коментария выше.

Отлаживаться на Нитре не реально. Процесс будет слишком долгим.

Ну, и особо смысла нет во всем этом.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: [Nemerle] Codegen quality
От: VladD2 Российская Империя www.nemerle.org
Дата: 04.03.17 11:58
Оценка: 18 (1)
Здравствуйте, rameel, Вы писали:

R>Результы изменений: джит полностью устранил проверку выхода за границу массива, проверку на null и вызов чего-то там на каждой итерации цикла

R>
R>Before:  1605 ms,  ips:    622 993,61
R> After:   329 ms,  ips:  3 031 065,39
R>


R>5 кратное ускорение на простом цикле


Смерджил и обновил инсталлятор. Так что теперь это изменение доступно всем.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: [Nemerle] Codegen quality
От: rameel https://github.com/rsdn/CodeJam
Дата: 04.03.17 12:25
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Смерджил и обновил инсталлятор. Так что теперь это изменение доступно всем.


Ага, видел

Я еще нашел, где можно получить заметное ускорение и inline ability для многих мелких методов. Это match, который очень активно используется, явно и неявно в логических выражениях и операциях (и/или). Сейчас там генерируется очень пушистый IL. Например, много бесполезных джампов типа таких (выписал из ilspy как пример):

IL_005a: br IL_00a2
...
IL_0077: br IL_0081
IL_007c: br IL_005a
IL_0081: br IL_00a2
...
IL_009d: br IL_005a

IL_00a2: ret


Разбираюсь с этим потихоньку. Как первый этап: сейчас избавился от пустого else, который генерирует джамп на следующую инструкцию, коих в проекте nemerle оказалось почти 3000 штук (подсчитал через генерацию варнингов).
match (expr)
{
    | true => ...
    | _    => ();
}

Но все это дело надо обобщить.
... << RSDN@Home 1.0.0 alpha 5 rev. 0>>
Re[4]: [Nemerle] Codegen quality
От: VladD2 Российская Империя www.nemerle.org
Дата: 04.03.17 12:31
Оценка:
Здравствуйте, rameel, Вы писали:

R>Разбираюсь с этим потихоньку. Как первый этап: сейчас избавился от пустого else, который генерирует джамп на следующую инструкцию, коих в проекте nemerle оказалось почти 3000 штук (подсчитал через генерацию варнингов).


А даст ли это что-то?

Ты ассемблер к подобным случаям смотрел? Наверняка джит пустые переходы выкидывает.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: [Nemerle] Codegen quality
От: rameel https://github.com/rsdn/CodeJam
Дата: 04.03.17 13:57
Оценка: 64 (2)
Здравствуйте, VladD2, Вы писали:

VD>А даст ли это что-то?


В совокупности.

VD>Ты ассемблер к подобным случаям смотрел? Наверняка джит пустые переходы выкидывает.


Да, джит пустые переходы мержит, но это если он конкретный метод разбирает, там ве нормально, но вот инлайнинг для мелких методов просто перестает работать. Вот такой код для примера уже не инлайнится:
public IsNull(a: object, b: object, c: object) : bool
{
    a != null && b != null && c != null;
}


Но это плохой пример. Здесь всего 2 перехода с ветки на ветку генерируется. В этом примере, конкретно, больше влиет то, что для самой проверки на null генерируется 6 инструкций вместо 2 или 12 байт вместо 3
IL_0007: ldarg.1
IL_0008: ldnull
IL_0009: ceq
IL_000b: ldc.i4.0
IL_000c: ceq
IL_000e: br IL_0014


И к сожалению, все это отражается на том, какой в итоге асм будет сгенерирован джитом. Текущий джит та еще редиска. Вот, что джит генерирует для шарпа
            if (a != null && b != null && c != null)
00007FFBEBED04A4  test        rsi,rsi  
00007FFBEBED04A7  je          00007FFBEBED04BD  
00007FFBEBED04A9  test        rdi,rdi  
00007FFBEBED04AC  je          00007FFBEBED04BD  
00007FFBEBED04AE  test        rbx,rbx  
00007FFBEBED04B1  je          00007FFBEBED04BD  
                Console.WriteLine(10);
00007FFBEBED04B3  mov         ecx,0Ah  
00007FFBEBED04B8  call        00007FFC53FD7BE0  

00007FFBEBED04BD


И вот что для немерле
            when (a != null && b != null && c != null)
00007FFBEBEC04D7  test        rsi,rsi  
00007FFBEBEC04DA  je          00007FFBEBEC0500  
00007FFBEBEC04DC  test        rdi,rdi  
00007FFBEBEC04DF  setne       cl  
00007FFBEBEC04E2  movzx       ecx,cl  
00007FFBEBEC04E5  test        ecx,ecx  
00007FFBEBEC04E7  je          00007FFBEBEC0500  
00007FFBEBEC04E9  test        rbx,rbx  
00007FFBEBEC04EC  setne       cl  
00007FFBEBEC04EF  movzx       ecx,cl  
00007FFBEBEC04F2  test        ecx,ecx  
00007FFBEBEC04F4  je          00007FFBEBEC0500  
                Console.WriteLine(10);
00007FFBEBEC04F6  mov         ecx,0Ah  
00007FFBEBEC04FB  call        00007FFC53FD7C10  

00007FFBEBEC0500
... << RSDN@Home 1.0.0 alpha 5 rev. 0>>
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.