Efficient C Question: Global variables

Ask anything your want about Megadrive/Genesis programming.

Moderator: BigEvilCorporation

Shiru
Very interested
Posts: 786
Joined: Sat Apr 07, 2007 3:11 am
Location: Russia, Moscow
Contact:

Post by Shiru » Sat Mar 24, 2012 6:59 pm

These are interesting and useful results, thanks. That's cool that local vars are faster.

djcouchycouch
Very interested
Posts: 710
Joined: Sat Feb 18, 2012 2:44 am

Post by djcouchycouch » Sat Mar 24, 2012 7:54 pm

Shiru wrote:These are interesting and useful results, thanks. .
You're welcome!

Of course the numbers are with the assumption that I'm benchmarking correctly :)

fdarkangel
Interested
Posts: 24
Joined: Sun Dec 17, 2006 8:28 pm
Location: Osaka, Japan

Post by fdarkangel » Thu Mar 29, 2012 5:53 am

djcouchycouch wrote:I don't know how output the C code into assembly, though. Sorry about that.
You can use GCC's -S option.
The output for http://dl.dropbox.com/u/17303735/performancetest001.c is (using SGDK's "default" options, implying -O1)

Code: Select all

#NO_APP
	.file	"performancetest001.c"
	.text
	.align	2
	.globl	Print
	.type	Print, @function
Print:
	lea (-16,%sp),%sp
	movm.l #0x3020,-(%sp)
	move.l 36(%sp),%d3
	move.l 40(%sp),%d2
	pea 16.w
	lea (16,%sp),%a2
	move.l %a2,-(%sp)
	move.l 40(%sp),-(%sp)
	jbsr uintToStr
	move.w %d2,-(%sp)
	clr.w -(%sp)
	move.w %d3,-(%sp)
	clr.w -(%sp)
	move.l %a2,-(%sp)
	jbsr VDP_drawText
	lea (24,%sp),%sp
	movm.l (%sp)+,#0x40c
	lea (16,%sp),%sp
	rts
	.size	Print, .-Print
	.local	YPrintCoord
	.comm	YPrintCoord,2,2
	.align	2
	.globl	RunTest
	.type	RunTest, @function
RunTest:
	movm.l #0x3020,-(%sp)
	move.l 24(%sp),%a2
	jbsr getSubTick
	move.l %d0,%d3
	move.l 20(%sp),%d2
	subq.l #1,%d2
	moveq #-1,%d0
	cmp.l %d2,%d0
	jbeq .L7
	.align	2
.L5:
	jbsr (%a2)
	dbra %d2,.L5
	clr.w %d2
	subq.l #1,%d2
	jbcc .L5
.L7:
	jbsr getSubTick
	move.l %d0,%d2
	moveq #0,%d0
	move.w YPrintCoord,%d0
	move.l %d0,-(%sp)
	clr.l -(%sp)
	move.l 24(%sp),-(%sp)
	jbsr VDP_drawText
	moveq #0,%d0
	move.w YPrintCoord,%d0
	move.l %d0,-(%sp)
	pea 24.w
	sub.l %d3,%d2
	move.l %d2,-(%sp)
	jbsr Print
	addq.w #1,YPrintCoord
	lea (24,%sp),%sp
	movm.l (%sp)+,#0x40c
	rts
	.size	RunTest, .-RunTest
	.align	2
	.globl	RunTestPlayerParameter
	.type	RunTestPlayerParameter, @function
RunTestPlayerParameter:
	movm.l #0x3820,-(%sp)
	move.l 28(%sp),%a2
	move.l 32(%sp),%d3
	jbsr getSubTick
	move.l %d0,%d4
	move.l 24(%sp),%d2
	subq.l #1,%d2
	moveq #-1,%d0
	cmp.l %d2,%d0
	jbeq .L13
	.align	2
.L11:
	move.l %d3,-(%sp)
	jbsr (%a2)
	addq.l #4,%sp
	dbra %d2,.L11
	clr.w %d2
	subq.l #1,%d2
	jbcc .L11
.L13:
	jbsr getSubTick
	move.l %d0,%d2
	moveq #0,%d0
	move.w YPrintCoord,%d0
	move.l %d0,-(%sp)
	clr.l -(%sp)
	move.l 28(%sp),-(%sp)
	jbsr VDP_drawText
	moveq #0,%d0
	move.w YPrintCoord,%d0
	move.l %d0,-(%sp)
	pea 24.w
	sub.l %d4,%d2
	move.l %d2,-(%sp)
	jbsr Print
	addq.w #1,YPrintCoord
	lea (24,%sp),%sp
	movm.l (%sp)+,#0x41c
	rts
	.size	RunTestPlayerParameter, .-RunTestPlayerParameter
	.align	2
	.globl	TestFunction_ModifyGlobals
	.type	TestFunction_ModifyGlobals, @function
TestFunction_ModifyGlobals:
	addq.w #1,PlayerX
	addq.w #1,PlayerY
	addq.w #1,SpeedX
	addq.w #1,SpeedY
	rts
	.size	TestFunction_ModifyGlobals, .-TestFunction_ModifyGlobals
	.align	2
	.globl	TestFunction_CopyGlobals
	.type	TestFunction_CopyGlobals, @function
TestFunction_CopyGlobals:
	move.w PlayerX,%d0
	addq.w #1,%d0
	move.w SpeedX,%d1
	addq.w #1,%d1
	move.w SpeedY,%a0
	addq.w #1,%a0
	move.w PlayerY,%a1
	addq.w #1,%a1
	move.w %a1,PlayerX
	move.w %d1,PlayerY
	move.w %a0,SpeedX
	move.w %d0,SpeedY
	rts
	.size	TestFunction_CopyGlobals, .-TestFunction_CopyGlobals
	.align	2
	.globl	TestFunction_ModifyGlobalStructPointer
	.type	TestFunction_ModifyGlobalStructPointer, @function
TestFunction_ModifyGlobalStructPointer:
	addq.w #1,Player
	addq.w #1,Player+2
	addq.w #1,Player+4
	addq.w #1,Player+6
	rts
	.size	TestFunction_ModifyGlobalStructPointer, .-TestFunction_ModifyGlobalStructPointer
	.align	2
	.globl	TestFunction_ModifyGlobalStruct
	.type	TestFunction_ModifyGlobalStruct, @function
TestFunction_ModifyGlobalStruct:
	addq.w #1,Player
	addq.w #1,Player+2
	addq.w #1,Player+4
	addq.w #1,Player+6
	rts
	.size	TestFunction_ModifyGlobalStruct, .-TestFunction_ModifyGlobalStruct
	.align	2
	.globl	TestFunction_ModifyParameterStructPointer
	.type	TestFunction_ModifyParameterStructPointer, @function
TestFunction_ModifyParameterStructPointer:
	move.l 4(%sp),%a0
	addq.w #1,(%a0)
	addq.w #1,2(%a0)
	addq.w #1,4(%a0)
	addq.w #1,6(%a0)
	rts
	.size	TestFunction_ModifyParameterStructPointer, .-TestFunction_ModifyParameterStructPointer
	.align	2
	.globl	TestFunction_DoesNothing
	.type	TestFunction_DoesNothing, @function
TestFunction_DoesNothing:
	rts
	.size	TestFunction_DoesNothing, .-TestFunction_DoesNothing
	.align	2
	.globl	TestFunction_DoesNothingWithPointerParameter
	.type	TestFunction_DoesNothingWithPointerParameter, @function
TestFunction_DoesNothingWithPointerParameter:
	rts
	.size	TestFunction_DoesNothingWithPointerParameter, .-TestFunction_DoesNothingWithPointerParameter
	.align	2
	.globl	TestFunction_InnerLoopWithLocalVariables
	.type	TestFunction_InnerLoopWithLocalVariables, @function
TestFunction_InnerLoopWithLocalVariables:
	move.l %d2,-(%sp)
	clr.w %d1
.L29:
	moveq #0,%d0
	.align	2
.L28:
	addq.l #1,%d0
	moveq #99,%d2
	cmp.l %d0,%d2
	jbcc .L28
	addq.w #1,%d1
	cmp.w #499,%d1
	jbls .L29
	move.l (%sp)+,%d2
	rts
	.size	TestFunction_InnerLoopWithLocalVariables, .-TestFunction_InnerLoopWithLocalVariables
	.local	cnt1.0
	.comm	cnt1.0,2,2
	.local	cnt2.1
	.comm	cnt2.1,4,2
	.local	cnt3.2
	.comm	cnt3.2,4,2
	.align	2
	.globl	TestFunction_InnerLoopWithLocalStaticVariables
	.type	TestFunction_InnerLoopWithLocalStaticVariables, @function
TestFunction_InnerLoopWithLocalStaticVariables:
	move.l %d2,-(%sp)
	clr.w (cnt1.0)
	move.l (cnt3.2),%d0
	clr.w %d1
.L42:
	move.l %d0,%a0
	moveq #0,%d0
	.align	2
.L41:
	lea (10,%a0),%a0
	addq.l #1,%d0
	moveq #99,%d2
	cmp.l %d0,%d2
	jbcc .L41
	move.l %d0,%a1
	move.l %a0,%d0
	addq.w #1,%d1
	cmp.w #499,%d1
	jbls .L42
	move.w %d1,(cnt1.0)
	move.l %a0,(cnt3.2)
	move.l %a1,(cnt2.1)
	move.l (%sp)+,%d2
	rts
	.size	TestFunction_InnerLoopWithLocalStaticVariables, .-TestFunction_InnerLoopWithLocalStaticVariables
	.align	2
	.globl	TestFunction_InnerLoopWithGlobalVariables
	.type	TestFunction_InnerLoopWithGlobalVariables, @function
TestFunction_InnerLoopWithGlobalVariables:
	move.l %d2,-(%sp)
	clr.w global_cnt1
	move.l global_cnt3,%d0
	clr.w %d1
.L57:
	move.l %d0,%a0
	moveq #0,%d0
	.align	2
.L56:
	lea (10,%a0),%a0
	addq.l #1,%d0
	moveq #99,%d2
	cmp.l %d0,%d2
	jbcc .L56
	move.l %d0,%a1
	move.l %a0,%d0
	addq.w #1,%d1
	cmp.w #499,%d1
	jbls .L57
	move.w %d1,global_cnt1
	move.l %a0,global_cnt3
	move.l %a1,global_cnt2
	move.l (%sp)+,%d2
	rts
	.size	TestFunction_InnerLoopWithGlobalVariables, .-TestFunction_InnerLoopWithGlobalVariables
	.local	cnt3.3
	.comm	cnt3.3,4,2
	.align	2
	.globl	TestFunction_InnerLoopWithLocalVariables2
	.type	TestFunction_InnerLoopWithLocalVariables2, @function
TestFunction_InnerLoopWithLocalVariables2:
	move.l %d2,-(%sp)
	clr.w %d2
	move.l (cnt3.3),%d1
.L72:
	moveq #0,%d0
	move.l %d1,%a0
	.align	2
.L71:
	lea (10,%a0),%a0
	addq.l #1,%d0
	moveq #99,%d1
	cmp.l %d0,%d1
	jbcc .L71
	move.l %a0,%d1
	addq.w #1,%d2
	cmp.w #499,%d2
	jbls .L72
	move.l %a0,(cnt3.3)
	move.l (%sp)+,%d2
	rts
	.size	TestFunction_InnerLoopWithLocalVariables2, .-TestFunction_InnerLoopWithLocalVariables2
	.section	.rodata.str1.1,"aMS",@progbits,1
.LC0:
	.string	"Modify Globals"
.LC1:
	.string	"Copy Globals"
.LC2:
	.string	"Mod Global Struct Ptr"
.LC3:
	.string	"Mod Global Struct"
.LC4:
	.string	"Mod Parameter Ptr"
.LC5:
	.string	"Mod Par Strct Stic Ptr"
.LC6:
	.string	"Empty Func"
.LC7:
	.string	"Empty Func /w Ptr"
.LC8:
	.string	"Loop Local Vars"
.LC9:
	.string	"Loop Global Vars"
.LC10:
	.string	"Loop Local Vars2"
.LC11:
	.string	"Loop Local Static Vars"
	.text
	.align	2
	.globl	main
	.type	main, @function
main:
	move.l %a3,-(%sp)
	move.l %a2,-(%sp)
	pea TestFunction_ModifyGlobals
	move.l #100000,-(%sp)
	pea .LC0
	lea RunTest,%a2
	jbsr (%a2)
	pea TestFunction_CopyGlobals
	move.l #100000,-(%sp)
	pea .LC1
	jbsr (%a2)
	pea TestFunction_ModifyGlobalStructPointer
	move.l #100000,-(%sp)
	pea .LC2
	jbsr (%a2)
	lea (32,%sp),%sp
	move.l #TestFunction_ModifyGlobalStruct,(%sp)
	move.l #100000,-(%sp)
	pea .LC3
	jbsr (%a2)
	pea Player
	pea TestFunction_ModifyParameterStructPointer
	move.l #100000,-(%sp)
	pea .LC4
	lea RunTestPlayerParameter,%a3
	jbsr (%a3)
	pea Player2
	pea TestFunction_ModifyParameterStructPointer
	move.l #100000,-(%sp)
	pea .LC5
	jbsr (%a3)
	lea (40,%sp),%sp
	move.l #TestFunction_DoesNothing,(%sp)
	move.l #100000,-(%sp)
	pea .LC6
	jbsr (%a2)
	pea Player2
	pea TestFunction_DoesNothingWithPointerParameter
	move.l #100000,-(%sp)
	pea .LC7
	jbsr (%a3)
	addq.w #1,YPrintCoord
	pea TestFunction_InnerLoopWithLocalVariables
	pea 1.w
	pea .LC8
	jbsr (%a2)
	lea (36,%sp),%sp
	move.l #TestFunction_InnerLoopWithGlobalVariables,(%sp)
	pea 1.w
	pea .LC9
	jbsr (%a2)
	pea TestFunction_InnerLoopWithLocalVariables2
	pea 1.w
	pea .LC10
	jbsr (%a2)
	pea TestFunction_InnerLoopWithLocalStaticVariables
	pea 1.w
	pea .LC11
	jbsr (%a2)
	lea (36,%sp),%sp
	moveq #0,%d0
	move.l (%sp)+,%a2
	move.l (%sp)+,%a3
	rts
	.size	main, .-main
	.comm	Player,8,2
	.comm	PlayerX,2,2
	.comm	PlayerY,2,2
	.comm	SpeedX,2,2
	.comm	SpeedY,2,2
	.local	Player2
	.comm	Player2,8,2
	.comm	global_cnt1,2,2
	.comm	global_cnt2,4,2
	.comm	global_cnt3,4,2
	.ident	"GCC: (GNU) 3.4.6"
Trivially, cnt3 is optimized away in TestFunction_InnerLoopWithLocalVariables, since it's affects nothing outside of this function. For -O0, we have

Code: Select all

#NO_APP
	.file	"performancetest001.c"
	.text
	.align	2
	.globl	Print
	.type	Print, @function
Print:
	lea (-20,%sp),%sp
	move.l 28(%sp),%d0
	move.l 32(%sp),%d1
	move.w %d0,18(%sp)
	move.w %d1,16(%sp)
	pea 16.w
	lea (4,%sp),%a0
	move.l %a0,-(%sp)
	move.l 32(%sp),-(%sp)
	jbsr uintToStr
	lea (12,%sp),%sp
	moveq #0,%d0
	move.w 16(%sp),%d0
	move.l %d0,-(%sp)
	moveq #0,%d0
	move.w 22(%sp),%d0
	move.l %d0,-(%sp)
	lea (8,%sp),%a0
	move.l %a0,-(%sp)
	jbsr VDP_drawText
	lea (12,%sp),%sp
	lea (20,%sp),%sp
	rts
	.size	Print, .-Print
	.local	YPrintCoord
	.comm	YPrintCoord,2,2
	.align	2
	.globl	RunTest
	.type	RunTest, @function
RunTest:
	lea (-12,%sp),%sp
	jbsr getSubTick
	move.l %d0,8(%sp)
	move.l 20(%sp),4(%sp)
.L3:
	subq.l #1,4(%sp)
	moveq #-1,%d0
	cmp.l 4(%sp),%d0
	jbeq .L4
	move.l 24(%sp),%a0
	jbsr (%a0)
	jbra .L3
	.align	2
.L4:
	jbsr getSubTick
	move.l %d0,(%sp)
	moveq #0,%d0
	move.w YPrintCoord,%d0
	move.l %d0,-(%sp)
	clr.l -(%sp)
	move.l 24(%sp),-(%sp)
	jbsr VDP_drawText
	lea (12,%sp),%sp
	moveq #0,%d0
	move.w YPrintCoord,%d0
	move.l %d0,-(%sp)
	pea 24.w
	move.l 8(%sp),%d0
	sub.l 16(%sp),%d0
	move.l %d0,-(%sp)
	jbsr Print
	lea (12,%sp),%sp
	addq.w #1,YPrintCoord
	lea (12,%sp),%sp
	rts
	.size	RunTest, .-RunTest
	.align	2
	.globl	RunTestPlayerParameter
	.type	RunTestPlayerParameter, @function
RunTestPlayerParameter:
	lea (-12,%sp),%sp
	jbsr getSubTick
	move.l %d0,8(%sp)
	move.l 20(%sp),4(%sp)
.L6:
	subq.l #1,4(%sp)
	moveq #-1,%d0
	cmp.l 4(%sp),%d0
	jbeq .L7
	move.l 28(%sp),-(%sp)
	move.l 28(%sp),%a0
	jbsr (%a0)
	addq.l #4,%sp
	jbra .L6
	.align	2
.L7:
	jbsr getSubTick
	move.l %d0,(%sp)
	moveq #0,%d0
	move.w YPrintCoord,%d0
	move.l %d0,-(%sp)
	clr.l -(%sp)
	move.l 24(%sp),-(%sp)
	jbsr VDP_drawText
	lea (12,%sp),%sp
	moveq #0,%d0
	move.w YPrintCoord,%d0
	move.l %d0,-(%sp)
	pea 24.w
	move.l 8(%sp),%d0
	sub.l 16(%sp),%d0
	move.l %d0,-(%sp)
	jbsr Print
	lea (12,%sp),%sp
	addq.w #1,YPrintCoord
	lea (12,%sp),%sp
	rts
	.size	RunTestPlayerParameter, .-RunTestPlayerParameter
	.align	2
	.globl	TestFunction_ModifyGlobals
	.type	TestFunction_ModifyGlobals, @function
TestFunction_ModifyGlobals:
	addq.w #1,PlayerX
	addq.w #1,PlayerY
	addq.w #1,SpeedX
	addq.w #1,SpeedY
	rts
	.size	TestFunction_ModifyGlobals, .-TestFunction_ModifyGlobals
	.align	2
	.globl	TestFunction_CopyGlobals
	.type	TestFunction_CopyGlobals, @function
TestFunction_CopyGlobals:
	subq.w #8,%sp
	move.w PlayerX,6(%sp)
	move.w PlayerY,4(%sp)
	move.w SpeedX,2(%sp)
	move.w SpeedY,(%sp)
	addq.w #1,6(%sp)
	addq.w #1,4(%sp)
	addq.w #1,2(%sp)
	addq.w #1,(%sp)
	move.w 4(%sp),PlayerX
	move.w 2(%sp),PlayerY
	move.w (%sp),SpeedX
	move.w 6(%sp),SpeedY
	addq.w #8,%sp
	rts
	.size	TestFunction_CopyGlobals, .-TestFunction_CopyGlobals
	.align	2
	.globl	TestFunction_ModifyGlobalStructPointer
	.type	TestFunction_ModifyGlobalStructPointer, @function
TestFunction_ModifyGlobalStructPointer:
	subq.w #4,%sp
	move.l #Player,(%sp)
	move.l (%sp),%a0
	addq.w #1,(%a0)
	move.l (%sp),%a0
	addq.w #1,2(%a0)
	move.l (%sp),%a0
	addq.w #1,4(%a0)
	move.l (%sp),%a0
	addq.w #1,6(%a0)
	addq.w #4,%sp
	rts
	.size	TestFunction_ModifyGlobalStructPointer, .-TestFunction_ModifyGlobalStructPointer
	.align	2
	.globl	TestFunction_ModifyGlobalStruct
	.type	TestFunction_ModifyGlobalStruct, @function
TestFunction_ModifyGlobalStruct:
	addq.w #1,Player
	addq.w #1,Player+2
	addq.w #1,Player+4
	addq.w #1,Player+6
	rts
	.size	TestFunction_ModifyGlobalStruct, .-TestFunction_ModifyGlobalStruct
	.align	2
	.globl	TestFunction_ModifyParameterStructPointer
	.type	TestFunction_ModifyParameterStructPointer, @function
TestFunction_ModifyParameterStructPointer:
	move.l 4(%sp),%a0
	addq.w #1,(%a0)
	move.l 4(%sp),%a0
	addq.w #1,2(%a0)
	move.l 4(%sp),%a0
	addq.w #1,4(%a0)
	move.l 4(%sp),%a0
	addq.w #1,6(%a0)
	rts
	.size	TestFunction_ModifyParameterStructPointer, .-TestFunction_ModifyParameterStructPointer
	.align	2
	.globl	TestFunction_DoesNothing
	.type	TestFunction_DoesNothing, @function
TestFunction_DoesNothing:
	rts
	.size	TestFunction_DoesNothing, .-TestFunction_DoesNothing
	.align	2
	.globl	TestFunction_DoesNothingWithPointerParameter
	.type	TestFunction_DoesNothingWithPointerParameter, @function
TestFunction_DoesNothingWithPointerParameter:
	rts
	.size	TestFunction_DoesNothingWithPointerParameter, .-TestFunction_DoesNothingWithPointerParameter
	.align	2
	.globl	TestFunction_InnerLoopWithLocalVariables
	.type	TestFunction_InnerLoopWithLocalVariables, @function
TestFunction_InnerLoopWithLocalVariables:
	lea (-12,%sp),%sp
	clr.w 10(%sp)
.L16:
	cmp.w #499,10(%sp)
	jbhi .L15
	clr.l 6(%sp)
.L19:
	moveq #99,%d0
	cmp.l 6(%sp),%d0
	jbcs .L18
	moveq #10,%d0
	add.l %d0,2(%sp)
	addq.l #1,6(%sp)
	jbra .L19
	.align	2
.L18:
	addq.w #1,10(%sp)
	jbra .L16
	.align	2
.L15:
	lea (12,%sp),%sp
	rts
	.size	TestFunction_InnerLoopWithLocalVariables, .-TestFunction_InnerLoopWithLocalVariables
	.local	cnt1.0
	.comm	cnt1.0,2,2
	.local	cnt2.1
	.comm	cnt2.1,4,2
	.local	cnt3.2
	.comm	cnt3.2,4,2
	.align	2
	.globl	TestFunction_InnerLoopWithLocalStaticVariables
	.type	TestFunction_InnerLoopWithLocalStaticVariables, @function
TestFunction_InnerLoopWithLocalStaticVariables:
	clr.w (cnt1.0)
.L23:
	cmp.w #499,(cnt1.0).l
	jbhi .L22
	clr.l (cnt2.1)
.L26:
	moveq #99,%d0
	cmp.l (cnt2.1).l,%d0
	jbcs .L25
	moveq #10,%d0
	add.l %d0,(cnt3.2)
	addq.l #1,(cnt2.1)
	jbra .L26
	.align	2
.L25:
	addq.w #1,(cnt1.0)
	jbra .L23
	.align	2
.L22:
	rts
	.size	TestFunction_InnerLoopWithLocalStaticVariables, .-TestFunction_InnerLoopWithLocalStaticVariables
	.align	2
	.globl	TestFunction_InnerLoopWithGlobalVariables
	.type	TestFunction_InnerLoopWithGlobalVariables, @function
TestFunction_InnerLoopWithGlobalVariables:
	clr.w global_cnt1
.L30:
	cmp.w #499,global_cnt1.l
	jbhi .L29
	clr.l global_cnt2
.L33:
	moveq #99,%d0
	cmp.l global_cnt2.l,%d0
	jbcs .L32
	moveq #10,%d0
	add.l %d0,global_cnt3
	addq.l #1,global_cnt2
	jbra .L33
	.align	2
.L32:
	addq.w #1,global_cnt1
	jbra .L30
	.align	2
.L29:
	rts
	.size	TestFunction_InnerLoopWithGlobalVariables, .-TestFunction_InnerLoopWithGlobalVariables
	.local	cnt3.3
	.comm	cnt3.3,4,2
	.align	2
	.globl	TestFunction_InnerLoopWithLocalVariables2
	.type	TestFunction_InnerLoopWithLocalVariables2, @function
TestFunction_InnerLoopWithLocalVariables2:
	subq.w #8,%sp
	clr.w 6(%sp)
.L37:
	cmp.w #499,6(%sp)
	jbhi .L36
	clr.l 2(%sp)
.L40:
	moveq #99,%d0
	cmp.l 2(%sp),%d0
	jbcs .L39
	moveq #10,%d0
	add.l %d0,(cnt3.3)
	addq.l #1,2(%sp)
	jbra .L40
	.align	2
.L39:
	addq.w #1,6(%sp)
	jbra .L37
	.align	2
.L36:
	addq.w #8,%sp
	rts
	.size	TestFunction_InnerLoopWithLocalVariables2, .-TestFunction_InnerLoopWithLocalVariables2
	.section	.rodata
.LC0:
	.string	"Modify Globals"
.LC1:
	.string	"Copy Globals"
.LC2:
	.string	"Mod Global Struct Ptr"
.LC3:
	.string	"Mod Global Struct"
.LC4:
	.string	"Mod Parameter Ptr"
.LC5:
	.string	"Mod Par Strct Stic Ptr"
.LC6:
	.string	"Empty Func"
.LC7:
	.string	"Empty Func /w Ptr"
.LC8:
	.string	"Loop Local Vars"
.LC9:
	.string	"Loop Global Vars"
.LC10:
	.string	"Loop Local Vars2"
.LC11:
	.string	"Loop Local Static Vars"
	.text
	.align	2
	.globl	main
	.type	main, @function
main:
	pea TestFunction_ModifyGlobals
	move.l #100000,-(%sp)
	pea .LC0
	jbsr RunTest
	lea (12,%sp),%sp
	pea TestFunction_CopyGlobals
	move.l #100000,-(%sp)
	pea .LC1
	jbsr RunTest
	lea (12,%sp),%sp
	pea TestFunction_ModifyGlobalStructPointer
	move.l #100000,-(%sp)
	pea .LC2
	jbsr RunTest
	lea (12,%sp),%sp
	pea TestFunction_ModifyGlobalStruct
	move.l #100000,-(%sp)
	pea .LC3
	jbsr RunTest
	lea (12,%sp),%sp
	pea Player
	pea TestFunction_ModifyParameterStructPointer
	move.l #100000,-(%sp)
	pea .LC4
	jbsr RunTestPlayerParameter
	lea (16,%sp),%sp
	pea Player2
	pea TestFunction_ModifyParameterStructPointer
	move.l #100000,-(%sp)
	pea .LC5
	jbsr RunTestPlayerParameter
	lea (16,%sp),%sp
	pea TestFunction_DoesNothing
	move.l #100000,-(%sp)
	pea .LC6
	jbsr RunTest
	lea (12,%sp),%sp
	pea Player2
	pea TestFunction_DoesNothingWithPointerParameter
	move.l #100000,-(%sp)
	pea .LC7
	jbsr RunTestPlayerParameter
	lea (16,%sp),%sp
	addq.w #1,YPrintCoord
	pea TestFunction_InnerLoopWithLocalVariables
	pea 1.w
	pea .LC8
	jbsr RunTest
	lea (12,%sp),%sp
	pea TestFunction_InnerLoopWithGlobalVariables
	pea 1.w
	pea .LC9
	jbsr RunTest
	lea (12,%sp),%sp
	pea TestFunction_InnerLoopWithLocalVariables2
	pea 1.w
	pea .LC10
	jbsr RunTest
	lea (12,%sp),%sp
	pea TestFunction_InnerLoopWithLocalStaticVariables
	pea 1.w
	pea .LC11
	jbsr RunTest
	lea (12,%sp),%sp
	moveq #0,%d0
	rts
	.size	main, .-main
	.comm	Player,8,2
	.comm	PlayerX,2,2
	.comm	PlayerY,2,2
	.comm	SpeedX,2,2
	.comm	SpeedY,2,2
	.local	Player2
	.comm	Player2,8,2
	.comm	global_cnt1,2,2
	.comm	global_cnt2,4,2
	.comm	global_cnt3,4,2
	.ident	"GCC: (GNU) 3.4.6"
This time, TestFunction_InnerLoopWithLocalVariables accesses stack only.

According to this listing, the relevant instruction cycles are

Code: Select all

Effective Address Operand Calculation Timing

This table lists the number of clock periods required to compute an
instruction's effective address. It includes fetching of any extension
words, the address computation , and fetching of the memory operand.
The number of bus read and write cycles is shown in parenthesis as (r/w).
Note there are no write cycles involved in processing the effective address.

		Effective Address Calculation Times
		register			                         Byte,Word  Long

d(An)	 address register indirect with dis-	 8(2/0)     12(3/0)
	         placement	
xxx.W	 absolute short			      	       8(2/0)     12(3/0)
xxx.L	 absolute long				              12(3/0)    16(4/0)
so yes, globals are ordinarily slower. (The original website has listings for move instructions -and others- in detail, but the picture is basically this.)

Post Reply