Re[5]: Быстро проверить на BCD
От: rameel https://github.com/rsdn/CodeJam
Дата: 27.06.17 16:30
Оценка:
Здравствуйте, tyomchick, Вы писали:

T>Проверял я на С# .


Текущий JIT не достаточно прозорлив в отличие от компиляторов C++, которые умеют вот такое:
bool is_bcd1(unsigned int val)
{
  unsigned int possible_non_bcd = val & 0x88888888; // 8,9,A,B,C,D,E,F
  
  if ((possible_non_bcd >> 1) & val)
    return false; // C, D, E, F


  if ((possible_non_bcd >> 2) & val)
    return false; // A, B

  return true;
}

превратить вот в такое:
bool is_bcd3(unsigned int val)
{
  unsigned int possible_non_bcd = val & 0x88888888; // 8,9,A,B,C,D,E,F
  
  return (((possible_non_bcd >> 1) | (possible_non_bcd >> 2)) & val) == 0;
}


и сгенерировать одинаковый код. Вот пруф: https://godbolt.org/g/KJ8XLo

Для джита же эту оптимизацию нужно провести вручную.
public static bool is_bcd2(uint val)
{
    uint possible_non_bcd = val & 0x88888888; // 8,9,A,B,C,D,E,F

    return (((possible_non_bcd >> 1) | (possible_non_bcd >> 2)) & val) == 0;
}


Пруф: SharpLab

; C++
mov     eax, edi
and     eax, -2004318072
mov     edx, eax
shr     eax, 2
shr     edx
or      eax, edx
test    eax, edi
sete    al
ret

; JIT x86
mov   edx, ecx
and   edx, 0x88888888
mov   eax, edx
shr   eax, 1
shr   edx, 0x2
or    eax, edx
and   eax, ecx
setz  al
movzx eax, al
ret
... << RSDN@Home 1.0.0 alpha 5 rev. 0>>
Отредактировано 27.06.2017 16:35 rameel . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.