From 67a850e71202800d71690a8cd30623bcb9f8c54b Mon Sep 17 00:00:00 2001 From: Abdulaziz Ghuloum Date: Thu, 21 Dec 2006 16:22:07 +0300 Subject: [PATCH] Profiling timing shows that we can do interrupt checks with cost: * about 2.0 secs per 1 billion checks if the counter is kept in memory * about 0.5 secs per 1 billion checks if the counter is kept in register. --- lab/prof/Makefile | 6 ++-- lab/prof/int.s | 34 ++++++++++++++++++++ lab/prof/main | Bin 8843 -> 13444 bytes lab/prof/main.c | 37 ++++++++++++++++------ lab/prof/main.s | 77 --------------------------------------------- lab/prof/plot.gcx | Bin 0 -> 32193 bytes lab/prof/times.txt | 9 ++++++ 7 files changed, 72 insertions(+), 91 deletions(-) create mode 100644 lab/prof/int.s delete mode 100644 lab/prof/main.s create mode 100644 lab/prof/plot.gcx create mode 100644 lab/prof/times.txt diff --git a/lab/prof/Makefile b/lab/prof/Makefile index 1c6da0f..b1d3283 100644 --- a/lab/prof/Makefile +++ b/lab/prof/Makefile @@ -1,6 +1,4 @@ -main: main.c - gcc -m64 -O3 -Wall main.c -o main +main: main.c int.s + gcc -Wall main.c int.s -o main -main.s: main.c - gcc -m64 -O3 -Wall -fomit-frame-pointer -fno-PIC -S main.c diff --git a/lab/prof/int.s b/lab/prof/int.s new file mode 100644 index 0000000..66240f1 --- /dev/null +++ b/lab/prof/int.s @@ -0,0 +1,34 @@ + +.globl _interrupt_mem +_interrupt_mem: + movl 4(%esp), %eax +L_loop1: + subl $1, 0(%eax); + jz L_int1 + jmp L_loop1 +L_int1: + ret + +.globl _interrupt_reg +_interrupt_reg: + movl 4(%esp), %eax +L_loop2: + subl $1, %eax; + jz L_int2 + subl $1, %eax; + jz L_int2 + subl $1, %eax; + jz L_int2 + subl $1, %eax; + jz L_int2 + subl $1, %eax; + jz L_int2 + subl $1, %eax; + jz L_int2 + subl $1, %eax; + jz L_int2 + jmp L_loop2 +L_int2: + ret + + diff --git a/lab/prof/main b/lab/prof/main index 5c6055e1c7dce26ca6143fff78e6efc6b8d889dc..e4a985581c57f47e5574cc013f12e2324c0c6a06 100755 GIT binary patch literal 13444 zcmeHOU2GIp6u#RobOVJh(xCF^qKkhaEh-@mqG?SRL|dppg;?s%boRC#x;wMX-mR_D zK(f?iGg&3ziw`CejgQ8kgvg7j&{$Mrs=>rWADURqCJTv)B>sf3erI;ZE=$E%gZHNA z-tV4!&bjA&vrTrAvtR#t<$4`stQJxOSq$k4GB%Di0BM16-qp4}_Cjp;E^Pb}_Q8!S zTwT8)oH^ec+rPKsoP2ygtaR@J2;EJCb16n-8JG7r`bX9NO`5t0f}D^=PAoDrLfabV$A1H z?yf(r-dN}ZtehXrBvV{!eF;J8>KI|<&97e3wF2L+T;TnY7)UF#4LkM?yN{?JkIHv0}m6{Xl^^JJ{|SO-qq% zda4ONMqim1vZwp*!!r8_V{d~j_kWf27<4bmosd-!dcOZOCgDHd`3g8tS?_x1#6cH? zY9sx>4g6cUgZ@t`58C^>@`;)i1BwB~fMP%~pcqgL{P!6+$a0smv%h37hn?PF?m(2~ zJ43mSXfS&&@Yzo_fv=zn73d4n)$ZJ-eb4X7Uf$r0)jPdmCl-3AKEhb;i4e_ef|#9# z@h>uUXXqWIcz5p0;?k|nazXZNph#2hn}*Xh$0jnx+!96}-xq7M6G10D{%z*Bd@6W~ zzWq6Dd_vZgrcZ?`HigbR7|X|Ia_!OJR51Dmq8EA@W2Nqyd~DX!PLg&zv`%amF+#au zw6GF>r-Fzy1wC$*(RwN;cQ_hE_GHmRYOFsm!yD7_LHZV0S|5&JQ(E7M1vR7M#==Kn zAfG)8D<_;k@d3OjKzlTl&z`^$<&bNP7T$*eGAv;fP6GRsbrcT4YAQC1gCp6oP>o#T z#OfXQ>NlaohNxiqlLkeLUCeb)PsJ|K_uXqw=Att;?Q~xF^}SE9XL3=)>20Nk)4NI! zogbgbAkZvTFoL7vfw@3QH_-W9_vBP;!V7fX8Jl!EC*}{doC3wb=nRFUulL2dB(GjC zmE7C2lN~)T^4@a}D$WkFfUGJ0UfvV}GLpr#il!AbEu*QPraGExia(sA0_a_ZUKV&# z8xlM&656Q1#)@YWf*YnG4J~23ENrf8iG=%xCD3|yUO+cHm3qLDCR+!g!FTR&vj=o<9Y&7{PubRhsU?NqZ$fP&JYiWwnG{rMso9coVGbKM zeg@!nq@-o0kM|j79KWyNgCda>PQl9X>rK3(zm#B9)qfz=drjcfq85y@({LdT6oGX+ivyLVKnz} zlA2*M5TpxZSn#x#OeF+8N^Wd!+1xZBBv0vF4ra`uroIuzGt_ZJ$LVd1_owhX9NEwC UyzxP>Gbzcb>!@N&jYt@O0Y|~AbpQYW literal 8843 zcmeHNU1%It6uz5mlC90pwpy%UWkmx1ku=gu5QDBH^p=Jinxq7OxNLT3cgM`mth2K< ziKu~Xv_ra@2YvFzC!fS8EmbI{_Ms|*DLxn~A{H$h(i$s8r4L!ZGjk`|oz&(<=*t|q zbI*6rx!*na+}UO3-udpv)wLGJLXC{E29#|m*(SzjQIp(*!cl}6iXRwwZs5qX)LJj0 zdU#VrJWFsCVq{=!q~68pAFXd=5+gQ-aGXLOLRiYAMVc#qzScHO2BxG8iZIPVJbInXrf>h$9p!%XSBO~yJaWBwGxqh&9V`EAQD+c%PS_@{PCTTe0!xo;kx*0 z$({a6R;0~DPH_!>zSENLE7^}Qt)(a1Jw?_+Bny_Q>X~(1zaBFk?tE2gCtS1Q0SpsieeKoBs@rKD4B19@-C0yObH|M+8a{*s%Twb$RgKtVpd5HMy z`C>9YFD$~h=F@SHxVK8)GB@$bj(68A8I5rog>v>V%Iy~Ke`TvUXg<9tl*9K| zFZYKV$DoBa=7@O?PZcaB*Y!*n=Btjw97vFXAOk@Lf(!&12r_WnGVl`P_HVrO>mPjX zwFoa4qxOx`m!Y$l8hPl?3Z8-3^-(y)kH$yiBg4FOB^tNa4%*kb{k`4yEuN>iz5k3; z?fRIixpqGLb#WUnx7`i6vWMH>tn7HQ+iK=uU1^~!w=Z;@YB;`7tZ=*SWvB1bN|=`x zBD~bgihm83vk^Ym^p-=%`0Rq!P+dgB>vav44-p&UUF7AyPY`G2dEn|OU~vge7pRHe z;V`WwK3lb#Dz7@I=_$~hhsxNXz0B>4gZAZq`|rx5Xt2*$UO+V;A0904`Qci%8XvB9 zu7YWPe!klII~2+VFCPfKc#gEs>0ywU_fNxu0Ixb#Z_h%79@xLALMrrVRPFo`mTKou z&h=;K`U|cMqnt&(d=j3}&yYUj>YtHrx%#K1XQAJPJ|v;(BP=u-4Mkg9BJ(irLmLfw zbPZ0BYve={hLN>L-)soeV}4t6n4V}$%_p16;kVK9Uwo7c;@j!cRqufAh@Ve3lm8&f z6*>MRvVGI|Uc0Q__Z5*#Oei9yXo)E$C2~fps3}6#RZC51>a=2tWJ1#l)W!2RQg|UY zb0S^TlLc0QlaYQ4AgXWR8DG|0b@1MA-<9vBAISP6 zS#Q-pum>3kG7w}S$Uu;RAOk@Lf(!&12r>|4Ajm+Ffgl6_e+IAv#O}k^NS8b}r;P%_ zG5Nm!fW-SGejK3fEx)wXorS& zrpO+V{>KT!@Py>ICGMB_9f`g3x%YrWEJRd}&>3PaKIg+1efW|OFZ=MS5C7xCbRJ5x z*@#zZmC z2Dtl8K#$kEOUW{Ecr0#alCnMqlgOJ!MyGEFgve!uGN~ksmIB^H3Lhs3ML(vRhR#IV zFc`L;RGqn@pyz}#mCKkS^-97_KPF5iqvFic6a^(|sfJ!4@`42xGY>UsWleB8J5|Co hik7Nl$OOLBP%R8&nmYJhkj~@d11n9#CA0M%{sozC&_MtI diff --git a/lab/prof/main.c b/lab/prof/main.c index c052de3..6332f80 100644 --- a/lab/prof/main.c +++ b/lab/prof/main.c @@ -1,14 +1,31 @@ + #include - -long long foo(long long int x){ - return x+1; -} - #include -int main(int argc, char** argv){ - fprintf(stderr, "sizeof(long long int)=%ld\n", - sizeof(long long int)); - long long int x = 57; - x = foo(x); +#include + +typedef struct pcb{ + int counter; +} pcb; + +extern void interrupt_mem(pcb*); +extern void interrupt_reg(int); + +void usage(char* name){ + fprintf(stderr, "Usage: %s [mem|reg]\n", name); exit(-1); } + +int main(int argc, char** argv){ + int most_positive_number = 0x7FFFFFFF; + if(argc != 2) usage(argv[0]); + if(strcmp(argv[1], "reg") == 0){ + interrupt_reg(most_positive_number); + } else if(strcmp(argv[1], "mem") == 0){ + pcb x; + x.counter = most_positive_number; + interrupt_mem(&x); + } else { + usage(argv[0]); + } + return 0; +} diff --git a/lab/prof/main.s b/lab/prof/main.s deleted file mode 100644 index abed3c4..0000000 --- a/lab/prof/main.s +++ /dev/null @@ -1,77 +0,0 @@ - .text -.globl _foo -_foo: -LFB3: - leaq 1(%rdi), %rax - ret -LFE3: - .cstring -LC0: - .ascii "sizeof(long long int)=%ld\12\0" - .text -.globl _main -_main: -LFB20: - subq $8, %rsp -LCFI0: - movl $8, %edx - leaq LC0(%rip), %rsi - movq ___stderrp@GOTPCREL(%rip), %rax - movq (%rax), %rdi - xorl %eax, %eax - call _fprintf - movl $-1, %edi - call _exit -LFE20: - .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support -EH_frame1: - .set L$set$0,LECIE1-LSCIE1 - .long L$set$0 -LSCIE1: - .long 0x0 - .byte 0x1 - .ascii "zR\0" - .byte 0x1 - .byte 0x78 - .byte 0x10 - .byte 0x1 - .byte 0x10 - .byte 0xc - .byte 0x7 - .byte 0x8 - .byte 0x90 - .byte 0x1 - .align 3 -LECIE1: - .globl _foo.eh -_foo.eh: -LSFDE1: - .set L$set$1,LEFDE1-LASFDE1 - .long L$set$1 -LASFDE1: - .long LASFDE1-EH_frame1 - .quad LFB3-. - .set L$set$2,LFE3-LFB3 - .quad L$set$2 - .byte 0x0 - .align 3 -LEFDE1: - .globl _main.eh -_main.eh: -LSFDE3: - .set L$set$3,LEFDE3-LASFDE3 - .long L$set$3 -LASFDE3: - .long LASFDE3-EH_frame1 - .quad LFB20-. - .set L$set$4,LFE20-LFB20 - .quad L$set$4 - .byte 0x0 - .byte 0x4 - .set L$set$5,LCFI0-LFB20 - .long L$set$5 - .byte 0xe - .byte 0x10 - .align 3 -LEFDE3: - .subsections_via_symbols diff --git a/lab/prof/plot.gcx b/lab/prof/plot.gcx new file mode 100644 index 0000000000000000000000000000000000000000..894c3c442efff6e859f60713c787d7af3cf0ca13 GIT binary patch literal 32193 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 d#lHvckv~b~`j?O|