Path: csiph.com!v102.xanadu-bbs.net!xanadu-bbs.net!feeder.erje.net!eu.feeder.erje.net!eweka.nl!lightspeed.eweka.nl!194.134.4.91.MISMATCH!news2.euro.net!postnews2.euro.net!news.wanadoo.nl!not-for-mail From: mhx@iae.nl (Marcel Hendrix) Subject: Re: Matrices Newsgroups: comp.lang.forth Message-ID: <58879100018434@frunobulax.edu> Date: Sun, 3 Feb 2013 12:48:45 +0200 References: X-Newsreader: iForth 2.0 console (October 21, 2006) Lines: 261 Organization: Wanadoo NNTP-Posting-Date: 03 Feb 2013 11:48:43 GMT NNTP-Posting-Host: s529d937f.adsl.online.nl X-Trace: 1359892123 dr6.euro.net 251 82.157.147.127:61929 X-Complaints-To: abuse@wanadoo.nl Xref: csiph.com comp.lang.forth:19381 m.a.m.hendrix@tue.nl wrote Re: Matrices > On Monday, January 28, 2013 10:11:32 AM UTC+1, Andrew Haley wrote: >>> Is it possible to have 'delayed compilation?' >> >> Whyever not? If you keep threaded code around you can recompile >> it to machine code whenever you want. > I should have stated more clearly that I am looking for a syntax > that hides the mechanics as much as possible. Of course the task > as such is possible -- everything is possible in Forth. I thank everybody for their thoughtful replies. I postponed the solution of this challenge and first looked at the main problem: inefficient array/matrix accesses. A better but memory-wise more costly indexing scheme that has been discussed at least twice on CLF, is to build a table for the row addresses when the matrix/array is allocated. This prevents having to multiply the row-size with the row index at run-time. It also allows to 'reshape' an already allocated array, again without multiplication cost at run-time. When the row and/or column index are known at compile time, the indexing collapses dramatically (see xzcopy below). An iForth particular trick is declare the array of row addresses as CONST-DATA, allowing the optimized to access the table at compile time. This manipulation is transparent to the user as it can be hidden in the GMATRIX words. With these trivial changes added to the XOPG source, I get results like the below. For reference i have added the VFX result when using the VFX-supplied fsl_util helper file. -marcel -- -------- .dfloat.p ( ask for double-precision float code [64 bits]) 2 2 GMATRIX x 2 2 GMATRIX z : testx ( -- ) x /rdim 0 DO x /cdim 0 DO LET x[j,i]=fdouble[2*j+i]: LOOP LOOP ; : testrx ( -- ) x /cdim 0 DO LET x[1,i]=fdouble[2*1+i]: LOOP ; : xzcopy ( -- ) LET z[0,0]=x[0,0]: LET z[1,1]=x[1,1]: LET z[0,1]=x[0,1]: LET z[1,0]=x[1,0]: ; testx x .gmat testrx x .gmat xzcopy z .gmat \ output FORTH> testx x .gmat [ 0.0000000000000000000e+0000 1.0000000000000000000e+0000 ] [ 2.0000000000000000000e+0000 3.0000000000000000000e+0000 ] ok FORTH> testrx x .gmat [ 0.0000000000000000000e+0000 1.0000000000000000000e+0000 ] [ 2.0000000000000000000e+0000 3.0000000000000000000e+0000 ] ok FORTH> xzcopy z .gmat [ 0.0000000000000000000e+0000 1.0000000000000000000e+0000 ] [ 2.0000000000000000000e+0000 3.0000000000000000000e+0000 ] ok \ code FORTH> see testx Flags: ANSI $01480F00 : testx $01480F0A push $01480A98 qword-offset $01480F10 xor rbx, rbx $01480F13 pop rcx $01480F14 call (DO) offset NEAR $01480F1E nop $01480F1F nop $01480F20 push rbx $01480F21 push $01480AA0 qword-offset $01480F27 xor rbx, rbx $01480F2A pop rcx $01480F2B call (DO) offset NEAR $01480F35 mov rax, rax $01480F38 mov rdi, [rbp #24 +] qword $01480F3C mov rax, [rbp 0 +] qword $01480F40 lea rdi, [rax rdi*2] qword $01480F44 push rdi $01480F45 fild [rsp] qword $01480F48 add rsp, 8 b# $01480F4C mov rdi, [rbp #24 +] qword $01480F50 mov rax, [rbp 0 +] qword $01480F54 lea rax, [rax*8 0 +] qword $01480F5C add rax, [rdi*8 $06C07470 +] qword $01480F64 fstp [rax] qword $01480F66 add [rbp 0 +] qword, 1 b# $01480F6B add [rbp 8 +] qword, 1 b# $01480F70 jno $01480F38 offset NEAR $01480F76 add rbp, #24 b# $01480F7A add [rbp 0 +] qword, 1 b# $01480F7F add [rbp 8 +] qword, 1 b# $01480F84 jno $01480F20 offset NEAR $01480F8A add rbp, #24 b# $01480F8E push rbx $01480F8F ; FORTH> see testrx Flags: ANSI $0147EBC0 : testrx $0147EBCA push $0147E6A0 qword-offset $0147EBD0 xor rbx, rbx $0147EBD3 pop rcx $0147EBD4 call (DO) offset NEAR $0147EBDE nop $0147EBDF nop $0147EBE0 mov rdi, [rbp 0 +] qword $0147EBE4 lea rdi, [rdi 2 +] qword $0147EBE8 push rdi $0147EBE9 fild [rsp] qword $0147EBEC add rsp, 8 b# $0147EBF0 mov rdi, [rbp 0 +] qword $0147EBF4 fstp [rdi*8 $066B75B0 +] qword $0147EBFB add [rbp 0 +] qword, 1 b# $0147EC00 add [rbp 8 +] qword, 1 b# $0147EC05 jno $0147EBE0 offset NEAR $0147EC0B add rbp, #24 b# $0147EC0F push rbx $0147EC10 ; FORTH> see xzcopy Flags: ANSI $01480FC0 : xzcopy $01480FCA fld $069975A0 qword-offset $01480FD0 fstp $069975E0 qword-offset $01480FD6 fld $069975B8 qword-offset $01480FDC fstp $069975F8 qword-offset $01480FE2 fld $069975A8 qword-offset $01480FE8 fstp $069975E8 qword-offset $01480FEE fld $069975B0 qword-offset $01480FF4 fstp $069975F0 qword-offset $01480FFA ; -- same for Vfx, using fsl_util -------------------- VFX Forth for Windows IA32 © MicroProcessor Engineering Ltd, 1998-2012 Version: 4.50 [build 3327] Build date: 17 April 2012 Free dictionary = 7561806 bytes [7384kb] include startup Including startup.fth Including %NdpDir%\Ndp387.fth Including %FslDir%\Vfx4Util.fth 2 2 double matrix x{{ 2 2 double matrix z{{ : testx ( -- ) 2 0 DO 2 0 DO j 2* i + S>F x{{ I I }} F! LOOP LOOP ; : testrx ( -- ) 2 0 DO 1 2* i + S>F x{{ 1 I }} F! LOOP ; : xzcopy ( -- ) x{{ 0 0 }} F@ z{{ 0 0 }} F! x{{ 0 1 }} F@ z{{ 0 1 }} F! x{{ 1 1 }} F@ z{{ 1 1 }} F! x{{ 1 0 }} F@ z{{ 1 0 }} F! ; see testx TESTX ( 004D0840 68B3084D00 ) PUSH 004D08B3 ( 004D0845 68FEFFFF7F ) PUSH 7FFFFFFE ( 004D084A 6A00 ) PUSH 00 ( 004D084C 90 ) NOP ( 004D084D 90 ) NOP ( 004D084E 90 ) NOP ( 004D084F 90 ) NOP ( 004D0850 68A4084D00 ) PUSH 004D08A4 ( 004D0855 68FEFFFF7F ) PUSH 7FFFFFFE ( 004D085A 6A00 ) PUSH 00 ( 004D085C 90 ) NOP ( 004D085D 90 ) NOP ( 004D085E 90 ) NOP ( 004D085F 90 ) NOP ( 004D0860 8B54240C ) MOV EDX, [ESP+0C] ( 004D0864 D1E2 ) SHL EDX, 1 ( 004D0866 8B0C24 ) MOV ECX, [ESP] ( 004D0869 03CA ) ADD ECX, EDX ( 004D086B 8D6DFC ) LEA EBP, [EBP+-04] ( 004D086E 895D00 ) MOV [EBP], EBX ( 004D0871 8BD9 ) MOV EBX, ECX ( 004D0873 E838A6FFFF ) CALL 004CAEB0 S>F ( 004D0878 8B1424 ) MOV EDX, [ESP] ( 004D087B 8B0D08044600 ) MOV ECX, [00460408] ( 004D0881 0FAFCA ) IMUL ECX, EDX ( 004D0884 03D1 ) ADD EDX, ECX ( 004D0886 0FAF1504044600 ) IMUL EDX, [00460404] ( 004D088D 031500044600 ) ADD EDX, [00460400] ( 004D0893 DB3A ) FSTP TBYTE 0 [EDX] ( 004D0895 83042401 ) ADD [ESP], 01 ( 004D0899 8344240401 ) ADD [ESP+04], 01 ( 004D089E 71C0 ) JNO 004D0860 ( 004D08A0 8D64240C ) LEA ESP, [ESP+0C] ( 004D08A4 83042401 ) ADD [ESP], 01 ( 004D08A8 8344240401 ) ADD [ESP+04], 01 ( 004D08AD 71A1 ) JNO 004D0850 ( 004D08AF 8D64240C ) LEA ESP, [ESP+0C] ( 004D08B3 C3 ) NEXT, ( 116 bytes, 38 instructions ) ok see testrx TESTRX ( 004D08E0 682A094D00 ) PUSH 004D092A ( 004D08E5 68FEFFFF7F ) PUSH 7FFFFFFE ( 004D08EA 6A00 ) PUSH 00 ( 004D08EC 90 ) NOP ( 004D08ED 90 ) NOP ( 004D08EE 90 ) NOP ( 004D08EF 90 ) NOP ( 004D08F0 8B1424 ) MOV EDX, [ESP] ( 004D08F3 83C202 ) ADD EDX, 02 ( 004D08F6 8D6DFC ) LEA EBP, [EBP+-04] ( 004D08F9 895D00 ) MOV [EBP], EBX ( 004D08FC 8BDA ) MOV EBX, EDX ( 004D08FE E8ADA5FFFF ) CALL 004CAEB0 S>F ( 004D0903 8B1424 ) MOV EDX, [ESP] ( 004D0906 031508044600 ) ADD EDX, [00460408] ( 004D090C 0FAF1504044600 ) IMUL EDX, [00460404] ( 004D0913 031500044600 ) ADD EDX, [00460400] ( 004D0919 DB3A ) FSTP TBYTE 0 [EDX] ( 004D091B 83042401 ) ADD [ESP], 01 ( 004D091F 8344240401 ) ADD [ESP+04], 01 ( 004D0924 71CA ) JNO 004D08F0 ( 004D0926 8D64240C ) LEA ESP, [ESP+0C] ( 004D092A C3 ) NEXT, ( 75 bytes, 23 instructions ) ok see xzcopy XZCOPY ( 004D0950 8B1500044600 ) MOV EDX, [00460400] ( 004D0956 DB2A ) FLD TBYTE 0 [EDX] ( 004D0958 8B1540044600 ) MOV EDX, [00460440] ( 004D095E DB3A ) FSTP TBYTE 0 [EDX] ( 004D0960 8B1500044600 ) MOV EDX, [00460400] ( 004D0966 031504044600 ) ADD EDX, [00460404] ( 004D096C DB2A ) FLD TBYTE 0 [EDX] ( 004D096E 8B1540044600 ) MOV EDX, [00460440] ( 004D0974 031544044600 ) ADD EDX, [00460444] ( 004D097A DB3A ) FSTP TBYTE 0 [EDX] ( 004D097C 8B1508044600 ) MOV EDX, [00460408] ( 004D0982 83C201 ) ADD EDX, 01 ( 004D0985 0FAF1504044600 ) IMUL EDX, [00460404] ( 004D098C 031500044600 ) ADD EDX, [00460400] ( 004D0992 DB2A ) FLD TBYTE 0 [EDX] ( 004D0994 8B1548044600 ) MOV EDX, [00460448] ( 004D099A 83C201 ) ADD EDX, 01 ( 004D099D 0FAF1544044600 ) IMUL EDX, [00460444] ( 004D09A4 031540044600 ) ADD EDX, [00460440] ( 004D09AA DB3A ) FSTP TBYTE 0 [EDX] ( 004D09AC 8B1504044600 ) MOV EDX, [00460404] ( 004D09B2 0FAF1508044600 ) IMUL EDX, [00460408] ( 004D09B9 031500044600 ) ADD EDX, [00460400] ( 004D09BF DB2A ) FLD TBYTE 0 [EDX] ( 004D09C1 8B1544044600 ) MOV EDX, [00460444] ( 004D09C7 0FAF1548044600 ) IMUL EDX, [00460448] ( 004D09CE 031540044600 ) ADD EDX, [00460440] ( 004D09D4 DB3A ) FSTP TBYTE 0 [EDX] ( 004D09D6 C3 ) NEXT, ( 135 bytes, 29 instructions ) ok