我用64位NASM编写了一个printint函数,它将一个整数打印到STDOUT。但是,它确实很慢,在进行了一些基准测试之后,我确定将整数转换为字符串是目前为止最慢的部分。
我当前将ints转换为字符串的策略如下所示:
如果数字为0,则跳到特例。如果数字为负数,则打印负号,将其转换为正整数,continue
)。
我试着用谷歌搜索别人是怎么做的,这和我做的差不多,除以10,直到这个数字是0。
以下是相关代码:
printint: ; num in edi
push rbp ; save base pointer
mov rbp, rsp ; place base pointer on stack
sub rsp, 20 ; align stack to keep 20 bytes for buffering
cmp edi, 0 ; compare num to 0
je _printint_zero ; 0 is special case
cmp edi, 0
jg _printint_pos ; don't print negative sign if positive
; print a negative sign (code not relevant)
xor edi, -1 ; convert into positive integer
add edi, 1
_printint_pos:
mov rbx, rsp ; set rbx to point to the end of the buffer
add rbx, 17
mov qword [rsp+8], 0 ; clear the buffer
mov word [rsp+16], 0 ; 10 bytes from [8,18)
_printint_loop:
cmp edi, 0 ; compare edi to 0
je _printint_done ; if edi == 0 then we are done
xor edx, edx ; prepare eax and edx for division
mov eax, edi
mov ecx, 10
div ecx ; divide and remainder by 10
mov edi, eax ; move quotient back to edi
add dl, 48 ; convert remainder to ascii
mov byte [rbx], dl ; move remainder to buffer
dec rbx ; shift 1 position to the left in buffer
jmp _printint_loop
_printint_done:
; print the buffer (code not relevant)
mov rsp, rbp ; restore stack and base pointers
pop rbp
ret
我如何优化它,使它能够运行得更快?或者,是否有更好的方法将整数转换为字符串?
我不想在C标准库中使用printf或任何其他函数。
发布于 2021-02-20 00:43:58
原来我搞错了瓶颈的源头。我的基准有缺陷。虽然微优化(如幻数乘法和更好的循环)确实有帮助,但最大的瓶颈是系统。
通过使用缓冲读写(缓冲区大小为16 kB),我能够实现我的目标,读取和打印整数比扫描和打印速度快。
创建一个输出缓冲区将一个特定的基准加速了4倍以上,而微优化则使其速度提高了大约25%。
对于将来偶然发现这篇文章的人来说,下面是我所做的优化:
我可以做的另一个可能的改进(但没有)是除以更大的基础和使用查找表,在注释中提到了phuclv。
https://stackoverflow.com/questions/66269798
复制相似问题