|
发表于 2022-10-27 02:43:24
|
显示全部楼层
花了几天时间,现学现卖,用64位汇编语言写了一遍
9个9,c要21秒多,汇编语言要2秒多
21.080 / 2.429 = 8.678
8.678 倍
20.384 / 2.077 = 9.814
c和python是 9.814 倍
什么概念呢?就是说汇编语言算2秒,python要算170多秒,就是这个概念,^_^
没有多次运行取平均值什么的,就是简单的看了看
汇编语言版本的是真的不好写
到此为止了,不玩了
- sh-5.1$ ls
- main.c main.s old
- sh-5.1$ cat main.c
- #include <stdio.h>
- #include <math.h>
- double get_n(void) {
- size_t n; scanf("%zu", &n);
- double s = 0;
- for(size_t i = 1; i <= n; ++i) {
- double x = pow(i, 0.5);
- s += i % 2 == 0 ? -x : x;
- }
- return s;
- }
- int main(void) {
- printf("%f\n", get_n());
- return 0;
- }
- sh-5.1$ cat main.s
- .section .text
- .global _start
- _start:
- # 调用read系统调用
- # 从标准输入读取一个数字,是字符串类型的
- # 存储到buff中
- movq $0, %rax # sys_read
- movq $0, %rdi # stdin
- leaq buff(%rip), %rsi # buff
- movq $1024, %rdx # count
- syscall
- # 下面把buff中的字符串转换成数字
- decq %rax # '\n'
- movq %rax, %rcx
- xorq %rax, %rax
- movq $10, %rdi
- 1: mulq %rdi # rax *= 10
- movzbq (%rsi), %rdx # dl = *(%rsi)
- incq %rsi
- subq $'0', %rdx
- addq %rdx, %rax
- decq %rcx
- cmpq $0, %rcx
- jg 1b
- movq %rax, %r8
- # 下面计算表达式的值
- movq $1, %rcx
- fldz
- 2: movq %rcx, temp(%rip)
- fildq temp(%rip)
- fsqrt # i的0.5次方就是对i开方
- fst %st(2)
- fchs
- testq $1, %rcx
- fcmovne %st(2), %st(0)
- faddp
- incq %rcx
- cmpq %r8, %rcx
- jng 2b
- ffree %st(1)
- # 下面把计算结果转换成字符串
- # 首先判断浮点数是不是负数
- # 如果是负数的话,要在字符串最前面加 '-'
- leaq buff(%rip), %rsi
- movb $'-', (%rsi)
- leaq 1(%rsi), %rax
- fldz
- fcomip %st(1), %st(0)
- cmovaq %rax, %rsi
- # 然后把整数部分和小数部分分开
- fld %st(0)
- fisttpq temp(%rip)
- fildq temp(%rip)
- fsubrp
- fabs
- fildq temp(%rip)
- fabs
- # 接下来处理整数部分
- 3: fld %st(0)
- movq $10, temp(%rip)
- fildq temp(%rip)
- fxch
- fprem
- fisttpq temp(%rip)
- movb temp(%rip), %al
- addb $'0', %al
- movb %al, (%rsi)
- incq %rsi
- fdivrp
- fisttpq temp(%rip)
- fildq temp(%rip)
- cmpq $0, temp(%rip)
- ja 3b
- fisttpq temp(%rip)
- # 上面弄出来的整数部分顺序是反的
- # 这里反序整数部分
- leaq buff(%rip), %rbx
- leaq 1(%rbx), %rax
- cmpb $'-', (%rbx)
- cmoveq %rax, %rbx
- leaq -1(%rsi), %rdi
- 4: movb (%rbx), %al
- movb (%rdi), %ah
- movb %al, (%rdi)
- movb %ah, (%rbx)
- incq %rbx
- decq %rdi
- cmpq %rbx, %rdi
- ja 4b
- # 下面处理小数部分
- # 保留小数点后15位
- movb $'.', (%rsi)
- incq %rsi
- movq $15, %rcx
- movq $10, temp(%rip)
- fildq temp(%rip)
- fxch
- 5: fmul %st(1), %st(0)
- fld %st(0)
- fisttpq temp(%rip)
- movb temp(%rip), %al
- addb $'0', %al
- movb %al, (%rsi)
- incq %rsi
- fildq temp(%rip)
- fsubrp
- decq %rcx
- cmpq $0, %rcx
- ja 5b
- # 字符串最后加一个 '\n'
- movb $'\n', (%rsi)
- incq %rsi
- # 调用write系统调用输出字符串
- movq $1, %rax # sys_write
- movq $1, %rdi # stdout
- movq %rsi, %rdx
- leaq buff(%rip), %rsi # buff
- subq %rsi, %rdx # count
- syscall
- # 调用exit系统调用退出程序
- movq $60, %rax # sys_exit
- movq $0, %rdi # status
- syscall
- retq
- .section .bss
- buff: .zero 1024
- temp: .zero 8
- sh-5.1$ gcc -O3 -g -Wall -o c main.c -lm
- sh-5.1$ as -O3 -g -o asm.o main.s
- sh-5.1$ ld -o asm asm.o
- sh-5.1$ ls
- asm asm.o c main.c main.s old
- sh-5.1$ time ./c <<EOF
- > 999999999
- > EOF
- 15811.768402
- real 0m20.280s
- user 0m20.241s
- sys 0m0.004s
- sh-5.1$ time ./asm <<EOF
- 999999999
- EOF
- 15811.768401701640368
- real 0m2.343s
- user 0m2.332s
- sys 0m0.004s
- sh-5.1$ time ./c <<EOF
- 999999999
- EOF
- 15811.768402
- real 0m21.210s
- user 0m21.080s
- sys 0m0.020s
- sh-5.1$ time ./asm <<EOF
- 999999999
- EOF
- 15811.768401701640368
- real 0m2.476s
- user 0m2.429s
- sys 0m0.007s
- sh-5.1$
复制代码 |
|