netch80: (Default)
[personal profile] netch80
Исходник:

bool FixMessage::isResendable() const
{
    unsigned type = getType();
    return type != FIX_MT_LOGON && type != FIX_MT_HEARTBEAT &&
           type != FIX_MT_TEST_REQUEST && type != FIX_MT_RESEND_REQUEST &&
           type != FIX_MT_SEQ_RESET && type != FIX_MT_LOGOUT;
}


Выхлоп gcc:

0000000000438570 <_ZNK10FixMessage12isResendableEv>:
  438570:       8b 4f 0c                mov    0xc(%rdi),%ecx
  438573:       b8 01 00 00 00          mov    $0x1,%eax
  438578:       83 e9 30                sub    $0x30,%ecx
  43857b:       83 f9 11                cmp    $0x11,%ecx
  43857e:       77 12                   ja     438592 <_ZNK10FixMessage12isResendableEv+0x22>
  438580:       b8 37 00 02 00          mov    $0x20037,%eax
  438585:       48 d3 e8                shr    %cl,%rax
  438588:       83 e0 01                and    $0x1,%eax
  43858b:       48 83 f0 01             xor    $0x1,%rax
  43858f:       83 e0 01                and    $0x1,%eax
  438592:       f3 c3                   repz retq 


Кто-то догадался, что сократить проверку диапазона близких значений вычитанием базы - отлично.
Беззнаковое сравнение результата вычитания - очень остроумно.
xor с rax, когда достаточно с eax - чего пытаются добиться?
Финальный and с константой - разве из предыдущих команд не ясно, что там останется один бит?

Считаем контрольную сумму:

unsigned checksum(const char *m_begin, const char *m_before_csum)
{
    unsigned csum = 0;
    for (const char *p = m_begin; p != m_before_csum; ++p) {
        csum += *p;
    }
    csum &= 0xff;
    return csum;
}


Генерируем с векторизацией. Не буду приводить всю сумасшедшую простыню, только основной цикл:

        pxor    %xmm0, %xmm0
        addq    %rdi, %r9
        xorl    %edi, %edi
        pxor    %xmm6, %xmm6
        pxor    %xmm4, %xmm4
.L9:
        movdqa  (%r9), %xmm3
        movdqa  %xmm6, %xmm1
        movdqa  %xmm4, %xmm5
        addq    $1, %rdi
        pcmpgtb %xmm3, %xmm1
        movdqa  %xmm3, %xmm2
        addq    $16, %r9
        cmpq    %rdi, %rdx
        punpcklbw       %xmm1, %xmm2
        punpckhbw       %xmm1, %xmm3
        pcmpgtw %xmm2, %xmm5
        movdqa  %xmm2, %xmm1
        punpckhwd       %xmm5, %xmm2
        punpcklwd       %xmm5, %xmm1
        movdqa  %xmm4, %xmm5
        pcmpgtw %xmm3, %xmm5
        paddd   %xmm1, %xmm0
        paddd   %xmm2, %xmm0
        movdqa  %xmm3, %xmm2
        punpcklwd       %xmm5, %xmm2
        paddd   %xmm2, %xmm0
        movdqa  %xmm0, %xmm1
        movdqa  %xmm3, %xmm0
        punpckhwd       %xmm5, %xmm0
        paddd   %xmm1, %xmm0
        ja      .L9


Кто может объяснить, чем нуль в xmm4 принципиально отличается от нуля в xmm6, и почему их нельзя было объединить?

В пропущенной части: до начальной границы 16 байт - короткий простой цикл по байту, но после последней такой границы - цикл развёрнут в 15 отдельных групп со сравнением в каждой на достижение конца входного массива.

Замена char на unsigned char убирает только сравнения (pcmpgt*). Два разных нуля остаются.

За окном шёл снег и два нулевых регистра.
(will be screened)
(will be screened if not validated)
If you don't have an account you can create one now.
HTML doesn't work in the subject.
More info about formatting

Profile

netch80: (Default)
netch80

January 2026

S M T W T F S
    1 23
45678910
11121314151617
18192021222324
25262728293031

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jan. 3rd, 2026 06:37 pm
Powered by Dreamwidth Studios