Сразу после того, как я посмотрел на этот вопрос, я обнаружил MULQ в сгенерированном коде при делении.
Полный код превращает большое двоичное число в куски в миллиард, чтобы его можно было легко преобразовать в строку.
C ++ код:
for_each(TempVec.rbegin(), TempVec.rend(), [&](Short & Num){
Remainder <<= 32;
Remainder += Num;
Num = Remainder / 1000000000;
Remainder %= 1000000000;//equivalent to Remainder %= DecimalConvert
});
Оптимизированная сгенерированная сборка
00007FF7715B18E8 lea r9,[rsi-4]
00007FF7715B18EC mov r13,12E0BE826D694B2Fh
00007FF7715B18F6 nop word ptr [rax+rax]
00007FF7715B1900 shl r8,20h
00007FF7715B1904 mov eax,dword ptr [r9]
00007FF7715B1907 add r8,rax
00007FF7715B190A mov rax,r13
00007FF7715B190D mul rax,r8
00007FF7715B1910 mov rcx,r8
00007FF7715B1913 sub rcx,rdx
00007FF7715B1916 shr rcx,1
00007FF7715B1919 add rcx,rdx
00007FF7715B191C shr rcx,1Dh
00007FF7715B1920 imul rax,rcx,3B9ACA00h
00007FF7715B1927 sub r8,rax
00007FF7715B192A mov dword ptr [r9],ecx
00007FF7715B192D lea r9,[r9-4]
00007FF7715B1931 lea rax,[r9+4]
00007FF7715B1935 cmp rax,r14
00007FF7715B1938 jne NumToString+0D0h (07FF7715B1900h)
Обратите внимание на инструкцию MUL на 5 строк ниже.
Этот сгенерированный код крайне не интуитивно понятен, я знаю, на самом деле он не похож на скомпилированный код, но DIV чрезвычайно медленный - 25 циклов для 32-разрядного деления и ~ 75 согласно этому графику на современных ПК по сравнению с MUL или IMUL (около 3 или 4 циклов), поэтому имеет смысл попытаться избавиться от DIV, даже если вам нужно добавить всевозможные дополнительные инструкции.
Я не совсем понимаю оптимизацию здесь, но если вы хотите увидеть рациональное и математическое объяснение использования времени компиляции и умножения для разделения констант, см. Эту статью .
Это пример того, как компилятор использует производительность и возможности полного 64-64-битного неусеченного умножения, не показывая кодеру c ++ никаких признаков этого.