Re: TCP/IP Checksumming

Heiko Schroeder (Heiko.Schroeder@post.rwth-aachen.de)
Tue, 26 Nov 1996 22:22 +0100 (MET)


Richard B. Johnson writes:
> On 25 Nov 1996, Tom May wrote:
> >
> > "Richard B. Johnson" <root@analogic.com> writes:
> >
> > No, they don't. Did you read the comment on the code I sent you,
> > which said to run it from a 32-bit segment? I at least do you the
> > courtesy of reading what you have to say. Using 32-bit instructions
> > in 16-bit DOS requires one or more prefixes to specify they are using
> > 32-bit addressing and/or operands. These prefixes require one extra
> > cycle each and prevent the instruction from running in the V-pipe
> > which means no parallelism is obtained. No parallelism gives a factor
> > of two performance hit for this code. The extra cycles for the
> > prefixes give even more performance hit. Take away those performance
> > hits and you will see the 10:1 ratio.
>
> The performance hit will be the same for all procedures tested. The
> purpose of the test-bench is to perform relative testing. The ratio
> changes less than 1 percent although the machine-cycles are less.

OK, I just hacked a Linux version of a "test-suite" using the
cycle counter. (I'm using a Pentium Pro, so I can access the rdtsc
instruction in user code.)

This way I can test the code in the 32-Bit environment it should be
tested in.

> Note that using a 32-bit segment does not eliminate the size-prefix for
> everything. In particular, you can't get a carry out of a 16-bit overflow
> into a 32-bit register. Using instructions that always access 32-bits
> forces one to accumulate carries and then fold them back at the end.
> This is shown to be inefficient even though no size prefix would
> be required.

Hmmm. The values below show quite the opposite. It is not that
difficult to fold the carries back, and what is more important, it
is done only once, not for every word accessed.

Here are the measured values for some of the functions used:

csum_partial: sum = 1a8a, min cycles 1406
csum_simple: sum = 1a8a, min cycles 6846
csum_opt: sum = 1a8a, min cycles 2455
csum_opt32: sum = 1a8a, min cycles 1434
csum_c: sum = 1a8a, min cycles 2626

csum_partial is the original Linux version.
csum_simple is the simple function using lodsw and loop, csum_opt is the
function that was best in the MS-DOS tests. csum_opt32 is csum_opt
changed to use 32-Bit memory accesses. And for comparison, there is
a C version of the checksumming algorithm in csum_c.

The results show quite clearly that the 32-bit acceses are the key to
good performance.

Appended to this mail is the source code for the test-suite.

CU
Heiko

begin 640 csum_test.c
M(VEN8VQU9&4@/'-T9&EO+F@^"@IS=&%T:6,@;&]N9R!L;VYG('0Q+"!T,CL*
M"G-T871I8R!I;FQI;F4@=F]I9"!R9'1S8RAL;VYG(&QO;F<@*G@I"GL*("`@
M87-M('9O;&%T:6QE("@B+F)Y=&4@,'@P9BP@,'@S,5QN7'0B"@D)(")M;W9L
M("4E96%X+"`E,%QN7'0B"@D)(")M;W9L("4E961X+"`E,2(*"0D@.B`B/6TB
M("@H*&QO;F<@*BEX*5LP72DL("(];2(H*"AL;VYG("HI>"E;,5TI"@D)(#HZ
M(F%X(BPB9'@B*3L*?0H*=6YS:6=N960@:6YT(&-S=6U?<&%R=&EA;"AC;VYS
M="!U;G-I9VYE9"!C:&%R("H@8G5F9BP@:6YT(&QE;BP@=6YS:6=N960@:6YT
M('-U;2D*>PH)("`O*@H)("`@*B!%>'!E<FEM96YT<R!W:71H(&5T:&5R;F5T
M(&%N9"!S;&EP(&-O;FYE8W1I;VYS('-H;W<@=&AA="!B=69F"@D@("`J(&ES
M(&%L:6=N960@;VX@96ET:&5R(&$@,BUB>71E(&]R(#0M8GET92!B;W5N9&%R
M>2X@(%=E(&=E="!A=`H)("`@*B!L96%S="!A(#)X('-P965D=7`@;VX@-#@V
M(&%N9"!096YT:75M(&EF(&ET(&ES(#0M8GET92!A;&EG;F5D+@H)("`@*B!&
M;W)T=6YA=&5L>2P@:70@:7,@96%S>2!T;R!C;VYV97)T(#(M8GET92!A;&EG
M;FUE;G0@=&\@-"UB>71E"@D@("`J(&%L:6=N;65N="!F;W(@=&AE('5N<F]L
M;&5D(&QO;W`N"@D@("`J+PH@("!R9'1S8R@F=#$I.PH)7U]A<VU?7R@B"@D@
M("`@=&5S=&P@)#(L("4E97-I"0DC($-H96-K(&%L:6=N;65N="X*"2`@("!J
M>B`R9@D)"2,@2G5M<"!I9B!A;&EG;FUE;G0@:7,@;VLN"@D@("`@<W5B;"`D
M,BP@)25E8W@)"2,@06QI9VYM96YT('5S97,@=7`@='=O(&)Y=&5S+@H)("`@
M(&IA92`Q9@D)"2,@2G5M<"!I9B!W92!H860@870@;&5A<W0@='=O(&)Y=&5S
M+@H)("`@(&%D9&P@)#(L("4E96-X"0DC(&5C>"!W87,@/"`R+B`@1&5A;"!W
M:71H(&ET+@H)("`@(&IM<"`T9@HQ.@D@("`@;6]V=R`H)25E<VDI+"`E)6)X
M"@D@("`@861D;"`D,BP@)25E<VD*"2`@("!A9&1W("4E8G@L("4E87@*"2`@
M("!A9&-L("0P+"`E)65A>`HR.@H)("`@(&UO=FP@)25E8W@L("4E961X"@D@
M("`@<VAR;"`D-2P@)25E8W@*"2`@("!J>B`R9@H)("`@('1E<W1L("4E97-I
M+"`E)65S:0HQ.@D@("`@;6]V;"`H)25E<VDI+"`E)65B>`H)("`@(&%D8VP@
M)25E8G@L("4E96%X"@D@("`@;6]V;"`T*"4E97-I*2P@)25E8G@*"2`@("!A
M9&-L("4E96)X+"`E)65A>`H)("`@(&UO=FP@."@E)65S:2DL("4E96)X"@D@
M("`@861C;"`E)65B>"P@)25E87@*"2`@("!M;W9L(#$R*"4E97-I*2P@)25E
M8G@*"2`@("!A9&-L("4E96)X+"`E)65A>`H)("`@(&UO=FP@,38H)25E<VDI
M+"`E)65B>`H)("`@(&%D8VP@)25E8G@L("4E96%X"@D@("`@;6]V;"`R,"@E
M)65S:2DL("4E96)X"@D@("`@861C;"`E)65B>"P@)25E87@*"2`@("!M;W9L
M(#(T*"4E97-I*2P@)25E8G@*"2`@("!A9&-L("4E96)X+"`E)65A>`H)("`@
M(&UO=FP@,C@H)25E<VDI+"`E)65B>`H)("`@(&%D8VP@)25E8G@L("4E96%X
M"@D@("`@;&5A(#,R*"4E97-I*2P@)25E<VD*"2`@("!D96,@)25E8W@*"2`@
M("!J;F4@,6(*"2`@("!A9&-L("0P+"`E)65A>`HR.@D@("`@;6]V;"`E)65D
M>"P@)25E8W@*"2`@("!A;F1L("0P>#%C+"`E)65D>`H)("`@(&IE(#1F"@D@
M("`@<VAR;"`D,BP@)25E9'@*"2`@("!T97-T;"`E)65S:2P@)25E<VD*,SH)
M("`@(&%D8VP@*"4E97-I*2P@)25E87@*"2`@("!L96$@-"@E)65S:2DL("4E
M97-I"@D@("`@9&5C("4E961X"@D@("`@:FYE(#-B"@D@("`@861C;"`D,"P@
M)25E87@*-#H)("`@(&%N9&P@)#,L("4E96-X"@D@("`@:GH@-V8*"2`@("!C
M;7!L("0R+"`E)65C>`H)("`@(&IB(#5F"@D@("`@;6]V=R`H)25E<VDI+"4E
M8W@*"2`@("!L96%L(#(H)25E<VDI+"4E97-I"@D@("`@:F4@-F8*"2`@("!S
M:&QL("0Q-BPE)65C>`HU.@D@("`@;6]V8B`H)25E<VDI+"4E8VP*-CH)("`@
M(&%D9&P@)25E8W@L)25E87@*"2`@("!A9&-L("0P+"`E)65A>`HW.@D@("`@
M;6]V;"`E)65A>"PE)65D>`H)("`@('-H<FP@)#$V+"4E96%X"@D@("`@861D
M=R`E)61X+"4E87@*"2`@("!A9&-W("0P+"4E87@B"@DZ("(]82(H<W5M*0H)
M.B`B,"(H<W5M*2P@(F,B*&QE;BDL(")3(BAB=69F*0H).B`B8G@B+"`B8W@B
M+"`B9'@B+"`B<VDB*3L*"7)D='-C*"9T,BD["@ER971U<FXH<W5M*3L*?0H*
M=6YS:6=N960@:6YT(&-S=6U?<VEM<&QE*&-O;G-T('5N<VEG;F5D(&-H87(@
M*F)U9F8L(&EN="!L96XL('5N<VEG;F5D(&EN="!S=6TI"GL*("`@<F1T<V,H
M)G0Q*3L*("`@7U]A<VU?7R@B"@EX;W(@)25E87@L)25E87@*"6-L9`HP.@EL
M;V1S=PH)861C=R`E)6%X+"4E9'@*"6QO;W`@,&(*"6%D8W<@)#`L)25D>"(*
M"2`@(#H@(CUD(BAS=6TI"@D@("`Z("(P(BAS=6TI+"`B8R(H;&5N(#X^(#$I
M+"`B4R(H8G5F9BD*"2`@(#H@(F%X(BPB8W@B+")D>"(L(G-I(BD["B`@(')D
M='-C*"9T,BD["B`@(')E='5R;B!S=6T["GT*"G5N<VEG;F5D(&EN="!C<W5M
M7V]P="AC;VYS="!U;G-I9VYE9"!C:&%R("IB=69F+"!I;G0@;&5N+"!U;G-I
M9VYE9"!I;G0@<W5M*0I["B`@(')D='-C*"9T,2D["B`@(&%S;2@B"@ES:')L
M("0Q+"`E)65C>`H)>&]R;"`E)65S:2P@)25E<VD*"C`Z"6-M<&P@)#,R+"`E
M)65C>`H):F%E("`Q9@H)8VUP;"`D,38L("4E96-X"@EJ864@,F8*("`@("`@
M("!C;7!L("0X+"`E)65C>`H@("`@("`@(&IA92`S9@H@("`@("`@(&-M<&P@
M)#0L("4E96-X"B`@("`@("`@:F%E(#1F"B`@("`@("`@:FUP(#9F"@HQ.@ES
M:')L("0Q+"`E)65S:0H)861C=R`@,"@E)65B>"DL("4E87@*"6%D8W<@(#(H
M)25E8G@I+"`E)6%X"@EA9&-W("`T*"4E96)X*2P@)25A>`H)861C=R`@-B@E
M)65B>"DL("4E87@*"6%D8W<@(#@H)25E8G@I+"`E)6%X"@EA9&-W(#$P*"4E
M96)X*2P@)25A>`H)861C=R`Q,B@E)65B>"DL("4E87@*"6%D8W<@,30H)25E
M8G@I+"`E)6%X"@EA9&-W(#$V*"4E96)X*2P@)25A>`H)861C=R`Q."@E)65B
M>"DL("4E87@*"6%D8W<@,C`H)25E8G@I+"`E)6%X"@EA9&-W(#(R*"4E96)X
M*2P@)25A>`H)861C=R`R-"@E)65B>"DL("4E87@*"6%D8W<@,C8H)25E8G@I
M+"`E)6%X"@EA9&-W(#(X*"4E96)X*2P@)25A>`H)861C=R`S,"@E)65B>"DL
M("4E87@*"6%D8W<@,S(H)25E8G@I+"`E)6%X"@EA9&-W(#,T*"4E96)X*2P@
M)25A>`H)861C=R`S-B@E)65B>"DL("4E87@*"6%D8W<@,S@H)25E8G@I+"`E
M)6%X"@EA9&-W(#0P*"4E96)X*2P@)25A>`H)861C=R`T,B@E)65B>"DL("4E
M87@*"6%D8W<@-#0H)25E8G@I+"`E)6%X"@EA9&-W(#0V*"4E96)X*2P@)25A
M>`H)861C=R`T."@E)65B>"DL("4E87@*"6%D8W<@-3`H)25E8G@I+"`E)6%X
M"@EA9&-W(#4R*"4E96)X*2P@)25A>`H)861C=R`U-"@E)65B>"DL("4E87@*
M"6%D8W<@-38H)25E8G@I+"`E)6%X"@EA9&-W(#4X*"4E96)X*2P@)25A>`H)
M861C=R`V,"@E)65B>"DL("4E87@*"6%D8W<@-C(H)25E8G@I+"`E)6%X"@EA
M9&-L("0P+"`E)65S:0H)861D;"`D-C0L("4E96)X"@ES=6)L("0S,BP@)25E
M8W@*"6IZ(#AF"@EJ;7`@,&(*"C(Z"7-H<FP@)#$L("4E97-I"@EA9&-W("`P
M*"4E96)X*2P@)25A>`H)861C=R`@,B@E)65B>"DL("4E87@*"6%D8W<@(#0H
M)25E8G@I+"`E)6%X"@EA9&-W("`V*"4E96)X*2P@)25A>`H)861C=R`@."@E
M)65B>"DL("4E87@*"6%D8W<@,3`H)25E8G@I+"`E)6%X"@EA9&-W(#$R*"4E
M96)X*2P@)25A>`H)861C=R`Q-"@E)65B>"DL("4E87@*"6%D8W<@,38H)25E
M8G@I+"`E)6%X"@EA9&-W(#$X*"4E96)X*2P@)25A>`H)861C=R`R,"@E)65B
M>"DL("4E87@*"6%D8W<@,C(H)25E8G@I+"`E)6%X"@EA9&-W(#(T*"4E96)X
M*2P@)25A>`H)861C=R`R-B@E)65B>"DL("4E87@*"6%D8W<@,C@H)25E8G@I
M+"`E)6%X"@EA9&-W(#,P*"4E96)X*2P@)25A>`H)861C;"`D,"P@)25E<VD*
M"6%D9&P@)#,R+"`E)65B>`H)<W5B;"`D,38L("4E96-X"@EJ>B`X9@H):FUP
M(#!B"@HS.@ES:')L("0Q+"`E)65S:0H)861C=R`@,"@E)65B>"DL("4E87@*
M"6%D8W<@(#(H)25E8G@I+"`E)6%X"@EA9&-W("`T*"4E96)X*2P@)25A>`H)
M861C=R`@-B@E)65B>"DL("4E87@*"6%D8W<@(#@H)25E8G@I+"`E)6%X"@EA
M9&-W(#$P*"4E96)X*2P@)25A>`H)861C=R`Q,B@E)65B>"DL("4E87@*"6%D
M8W<@,30H)25E8G@I+"`E)6%X"@EA9&-L("0P+"`E)65S:0H)861D;"`D,38L
M("4E96)X"@ES=6)L("0X+"`E)65C>`H):GH@.&8*"6IM<"`P8@H*-#H)<VAR
M;"`D,2P@)25E<VD*"6%D8W<@(#`H)25E8G@I+"`E)6%X"@EA9&-W("`R*"4E
M96)X*2P@)25A>`H)861C=R`@-"@E)65B>"DL("4E87@*"6%D8W<@(#8H)25E
M8G@I+"`E)6%X"@EA9&-L("0P+"`E)65S:0H)861D;"`D."P@)25E8G@*"7-U
M8FP@)#0L("4E96-X"@EJ>B`X9@H):FUP(#!B"@HU.@ES:')L("0Q+"`E)65S
M:0H)861C=R`@,"@E)65B>"DL("4E87@*"6%D8W<@(#(H)25E8G@I+"`E)6%X
M"@EA9&-L("0P+"`E)65S:0H)861D;"`D-"P@)25E8G@*"7-U8FP@)#(L("4E
M96-X"@EJ>B`X9B`O*B!D;VYE("HO"@EJ;7`@,&(*"C8Z"7-H<FP@)#$L("4E
M97-I"C<Z"6%D8W<@*"4E96)X*2P@)25A>`H)861C;"`D,BP@)25E8G@*"61E
M8VP@)25E8W@*"6IN>B`W8@H)8VUP=R`M,B@E)65B>"DL("4E87@*"6%D8VP@
M)#`L("4E97-I"C@Z"7-H<FP@)#$L("4E97-I"@EA9&-W("0P+"`E)6%X(@H@
M("`@("`@.B`B/6$B*'-U;2D*("`@("`@(#H@(C`B*'-U;2DL(")C(BAL96XI
M+"`B8B(H8G5F9BD*("`@("`@(#H@(F%X(BP@(F)X(BP@(F-X(BP@(G-I(BD[
M"B`@(')D='-C*"9T,BD["B`@(')E='5R;B!S=6T["GT*"G5N<VEG;F5D(&EN
M="!C<W5M7V]P=#,R*&-O;G-T('5N<VEG;F5D(&-H87(@*F)U9F8L(&EN="!L
M96XL('5N<VEG;F5D(&EN="!S=6TI"GL*("`@<F1T<V,H)G0Q*3L*("`@87-M
M*"(*"7-H<FP@)#$L("4E96-X"@EX;W)L("4E97-I+"`E)65S:0H*,#H)8VUP
M;"`D,S(L("4E96-X"@EJ864@(#%F"@EC;7!L("0Q-BP@)25E8W@*"6IA92`R
M9@H@("`@("`@(&-M<&P@)#@L("4E96-X"B`@("`@("`@:F%E(#-F"B`@("`@
M("`@8VUP;"`D-"P@)25E8W@*("`@("`@("!J864@-&8*("`@("`@("!J;7`@
M-F8*"C$Z"7-H<FP@)#$L("4E97-I"@EA9&-L("`P*"4E96)X*2P@)25E87@*
M"6%D8VP@(#0H)25E8G@I+"`E)65A>`H)861C;"`@."@E)65B>"DL("4E96%X
M"@EA9&-L(#$R*"4E96)X*2P@)25E87@*"6%D8VP@,38H)25E8G@I+"`E)65A
M>`H)861C;"`R,"@E)65B>"DL("4E96%X"@EA9&-L(#(T*"4E96)X*2P@)25E
M87@*"6%D8VP@,C@H)25E8G@I+"`E)65A>`H)861C;"`S,B@E)65B>"DL("4E
M96%X"@EA9&-L(#,V*"4E96)X*2P@)25E87@*"6%D8VP@-#`H)25E8G@I+"`E
M)65A>`H)861C;"`T-"@E)65B>"DL("4E96%X"@EA9&-L(#0X*"4E96)X*2P@
M)25E87@*"6%D8VP@-3(H)25E8G@I+"`E)65A>`H)861C;"`U-B@E)65B>"DL
M("4E96%X"@EA9&-L(#8P*"4E96)X*2P@)25E87@*"6%D8VP@)#`L("4E97-I
M"@EA9&1L("0V-"P@)25E8G@*"7-U8FP@)#,R+"`E)65C>`H):GH@.&8*"6IM
M<"`P8@H*,CH)<VAR;"`D,2P@)25E<VD*"6%D8VP@(#`H)25E8G@I+"`E)65A
M>`H)861C;"`@-"@E)65B>"DL("4E96%X"@EA9&-L("`X*"4E96)X*2P@)25E
M87@*"6%D8VP@,3(H)25E8G@I+"`E)65A>`H)861C;"`Q-B@E)65B>"DL("4E
M96%X"@EA9&-L(#(P*"4E96)X*2P@)25E87@*"6%D8VP@,C0H)25E8G@I+"`E
M)65A>`H)861C;"`R."@E)65B>"DL("4E96%X"@EA9&-L("0P+"`E)65S:0H)
M861D;"`D,S(L("4E96)X"@ES=6)L("0Q-BP@)25E8W@*"6IZ(#AF"@EJ;7`@
M,&(*"C,Z"7-H<FP@)#$L("4E97-I"@EA9&-L("`P*"4E96)X*2P@)25E87@*
M"6%D8VP@(#0H)25E8G@I+"`E)65A>`H)861C;"`@."@E)65B>"DL("4E96%X
M"@EA9&-L(#$R*"4E96)X*2P@)25E87@*"6%D8VP@)#`L("4E97-I"@EA9&1L
M("0Q-BP@)25E8G@*"7-U8FP@)#@L("4E96-X"@EJ>B`X9@H):FUP(#!B"@HT
M.@ES:')L("0Q+"`E)65S:0H)861C;"`@,"@E)65B>"DL("4E96%X"@EA9&-L
M("`T*"4E96)X*2P@)25E87@*"6%D8VP@)#`L("4E97-I"@EA9&1L("0X+"`E
M)65B>`H)<W5B;"`D-"P@)25E8W@*"6IZ(#AF"@EJ;7`@,&(*"C8Z"6UO=FP@
M)25E87@L("4E961X"@ES:')L("0Q-BP@)25E87@*"6%D9'<@)25D>"P@)25A
M>`H)861C=R`D,"P@)25A>`H)<VAR;"`D,2P@)25E<VD*-SH)861C=R`H)25E
M8G@I+"`E)6%X"@EA9&-L("0R+"`E)65B>`H)9&5C;"`E)65C>`H):FYZ(#=B
M"@EC;7!W("TR*"4E96)X*2P@)25A>`H)861C;"`D,"P@)25E<VD*.#H)<VAR
M;"`D,2P@)25E<VD*"6%D8VP@)#`L("4E96%X"@EM;W9L("4E96%X+"`E)65D
M>`H)<VAR;"`D,38L("4E96%X"@EA9&1W("4E9'@L("4E87@*"6%D8W<@)#`L
M("4E87@B"B`@("`@("`Z("(]82(H<W5M*0H@("`@("`@.B`B,"(H<W5M*2P@
M(F,B*&QE;BDL(")B(BAB=69F*0H@("`@("`@.B`B87@B+"`B8G@B+"`B8W@B
M+"`B9'@B+"`B<VDB*3L*("`@<F1T<V,H)G0R*3L*("`@<F5T=7)N('-U;3L*
M?0H*=6YS:6=N960@:6YT(&-S=6U?8RAC;VYS="!U;G-I9VYE9"!C:&%R("IB
M=69F+"!I;G0@;&5N+"!U;G-I9VYE9"!I;G0@<W5M*0I["B`@('5N<VEG;F5D
M(&EN="!H.PH@("!I;G0@:3L*("`@=6YS:6=N960@*F(["@H@("!R9'1S8R@F
M=#$I.PH@("!B(#T@8G5F9CL*("`@9F]R("AI/3`[(&D@/"`H;&5N/CXR*3L@
M:2LK*2!["B`@("`@(&@@/2!S=6T["B`@("`@('-U;2`K/2`J8BLK.PH@("`@
M("!I9B`H<W5M(#P@:"D*"2!S=6TK*SL*("`@?0H@("!I9B`H;&5N("8@,RD@
M>PH@("`@("!H(#T@<W5M.PH@("`@("!S=6T@*ST@*BAU;G-I9VYE9"!S:&]R
M="`J*6)U9F8["B`@("`@(&EF("AS=6T@/"!H*0H)('-U;2LK.PH@("`@("!I
M9B`H;&5N("8@,2D@>PH)(&@@/2!S=6T["@D@<W5M("L]("@H=6YS:6=N960@
M8VAA<B`J*6)U9F8I6S)=.PH)(&EF("AS=6T@/"!H*0H)("`@('-U;2LK.PH@
M("`@("!]"B`@('T*("`@:"`]('-U;2`F(#!X9F9F9CL*("`@<W5M(#X^/2`Q
M-CL*("`@<W5M("L](&@["B`@(&EF("AS=6T@/B`P>&9F9F8I"B`@("`@('-U
M;2LK.PH@("!R9'1S8R@F=#(I.PH@("!R971U<FX@<W5M("8@,'AF9F9F.PI]
M"@H*;&]N9R!D=6UM>3L*=6YS:6=N960@8VAA<B!B=69;,C`T.%T["@IV;VED
M(&UE87-U<F4H=6YS:6=N960@:6YT("@J9G5N8RDH*2P@8V]N<W0@8VAA<B`J
M9FYA;64I"GL*("`@:6YT('1D+"!M:6X["B`@(&EN="!I.PH@("!U;G-I9VYE
M9"!I;G0@<W5M.PH*("`@;6EN(#T@,3`P,#`P.PH@("!F;W(@*&D],#L@:2`\
M(#$P,#`P,#L@:2LK*2!["B`@("`@('-U;2`](&9U;F,H8G5F+"!S:7IE;V8H
M8G5F*2P@,"D["B`@("`@('1D(#T@=#(M=#$["B`@("`@(&EF("AT9"`\(&UI
M;BD*"2!M:6X@/2!T9#L*("`@?0H@("!P<FEN=&8H(B5S.B!S=6T@/2`E>"P@
M;6EN(&-Y8VQE<R`E9%QN(BP@9FYA;64L('-U;2P@;6EN*3L*?0HC9&5F:6YE
M(&UE87,H>"D@;65A<W5R92AX+"`C>"D*"FEN="!M86EN*'9O:60I"GL*("`@
M:6YT(&D["B`@(&-H87(@*G,["B`@(`H@("!S/6)U9CL*("`@9F]R("AI/3`[
M(&D\,3(X.R!I*RLI('L*("`@("`@;65M8W!Y*',L("))4"!086-K970N+BXN
M+BX@(BP@,38I.PH@("`@("!S("L](#$V.PH@("!]"B`@(&UE87,H8W-U;5]P
M87)T:6%L*3L*("`@;65A<RAC<W5M7W-I;7!L92D["B`@(&UE87,H8W-U;5]O
M<'0I.PH@("!M96%S*&-S=6U?;W!T,S(I.PH@("!M96%S*&-S=6U?8RD["B`@
4(')E='5R;B`P.PI]"@H*"2`@(`IT
`
end

-- 
+----------------------------------------+------------------------------------+
|Email:                                  | Snail-mail:  Heiko Schroeder       |
|                                        |              Lerchenweg 120        |
|  Heiko.Schroeder@Post.RWTH-Aachen.de   |              52223 Stolberg        |
|                                        |              GERMANY               |
+----------------------------------------+------------------------------------+