Re: [fpc-pascal] Effective memory allocation
Relooking at your timings and mine, it appears that you allocate 10x my count of register-size count of items and require 10x the FillChar which you need to initialize your filter array. My timing is about 80 ms and yours looks like 900 ms for 10x more register sized data, which look like the reasonable ratio since we may have difference in the way we get the timings (my timing routines beeing maybe a bit optimistic). Here I think the speed limit is the time it takes to effectively transfer the data to RAM and that whether you have a FillChar or FillQWord that ends up beeing STOSB or STOSQ, that is fully cached inside the CPU thus the limiting factor is the time it takes to move the initialized CPU cached data to the RAM.___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Effective memory allocation
My results : _Ptr:=GetMem(1)18 mus, 824 ns / GetMem _Ptr:=GetMem(1) + FillChar(_Ptr^,1,0)); 81 ms / GetMem + FillChar var ArInt:array of int32; . SetLength(ArInt, 1 shr 2); 81 ms / SetLength All timings are variable within [time, time+8%] on repeated runs as is generally the case for system timings. SetLength 0's (Internally calls FillChar) the array ArInt so to do a identical comparison you need to add the FillChar to the GetMem if it is your intention to 0 the array before using it. You have to compare things that do the same thing in the end. Tested on XP Pro Win32 Sp3 Intel Core 2CPU 6400 #@ 2.13GHz 2.05 GHr., 1.00 Gb RAM ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Thread Safety of String
My point of view after looking at the code. This code is not thread safe. Discussion gtest.sflag := inttostr(gtest.nflag) ; - will call fpc_AnsiStr_To_ShortStr fpc_AnsiStr_To_ShortStr is programmed as : procedure fpc_AnsiStr_To_ShortStr (out res: shortstring; const S2 : Ansistring);[Public, alias: 'FPC_ANSISTR_TO_SHORTSTR']; compilerproc; { Converts a AnsiString to a ShortString; } Var Size : SizeInt; begin if S2='' then res:='' else begin Size:=Length(S2); If Sizehigh(res) then Size:=high(res); Move (S2[1],res[1],Size); // 1° ~bk Copy the string byte(res[0]):=byte(Size); // 2° ~bk patch the length end; end; 1° and 2° (the processor instructions generated for the task) can not be guaranteed to be executed in order on most processors. + As far as I know, or at least that would be something that I would consider as true, pre-emptive multitasking may switch the threads during 1° or between and 1° and 2°. + Thread doing if gtest.sflag = '123456' then begin // 3° ~bk unfinished AnsiStr_To_ShortStr ? // gtest.sflag is equal to '123456' 3° ~bk unfinished AnsiStr_To_ShortStr : res might contain '1234567' with length 6 because if contained a length of 6 before step 2°, but the length=6 would be, for example, the residue length of the previous res= '263456' . And so on. My experience is that for these things one must use a CriticalSection or similar thread protection. Regards, Bruno ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Currency constant wrongly stored in generated EXE?
Lets restate the hole thing, considering unit ncon.pas and pexpr.pas units in FPC 2.6.4 compiler. 1° It is not possible, without using some ad hoc adjustements, to have always an EXACT CURRENCY stored in a DOUBLE or EXTENDED because Double or Extended being expressed as Sign*2^exp*Base2(n). Just start with 0.1 to see what I mean. 2° trealconstnode class stores the currency_literal value to value_real (type bestreal) then converts it to value_currency either in the trealconstnode.create or sets it in pexpr.pas function factor(getaddr,typeonly:boolean) : tnode; just after {$ifdef FPC_HAS_STR_CURRENCY} 3° c:=92233720368547; // The original problem multiple operations involve *1 (OK per see) and /1 (not so good) while parsing the constant to bestreal type before generating .EXE code. (bestreal is Extended on Intel I386 and Up and Double on ARM). 4° The compiler will not compain about Currency_Value:=0.9 whereas the max decimal precision is 0. for decimal part. 5° What I found is that only + or - operations on Currency's giving a Currency will be generated with plain Int64 addition and subtractions. Now what ? It would be interesting that someone who has an ARM based machine/compiler do some testing. Since currency is a very good type for accounting, you know Sum(Assets)-Sum(Liabilities)=Sum(Incomes)-Sum(Costs) - hopefully benefit and exact, some workarounds must be found. A basic way to circumvent the risks when absolutly necessary would be something like what is decribed next, not very Pascal clean I must admit : - Insure that the compiler will not see a literal currency when assigning or calculating a precise value containing a literal currency value. so short example, look at the ASM code generated. var c: currency; lInt64:Int64 absolute c; // Avoid use of Currency begin c:=0.9; // Accepted by the compiler ... and rounded to 1 c:=0.99986; // Accepted by the compiler ... and rounded to 0. c:=0.99984; // Accepted by the compiler ... and rounded to 0.9998 { The easy way but uses the FPU } c:=92233720368547; // - that might be wrongly evaluated by the Compiler (FPU usage) but nothing will be visible in the generated ASM regarding FPU evaluation, except in your case, an invalid HEX value c:=c+0.01; // - uses FPU writeln('c+0.01 with FPU=', c); { Clumsy but no FPU usage while compiling and executing } lInt64:=92233720368547; // - You can test but my bet is that it probably always correctly evaluated by the compiler lInt64:=lInt64+100; // Equivalent to c:=c+0.01 writeln('c+0.01 indirect no FPU=', c); readln; end; Your subject has been interesting and I'll be careful now with rounding and Currency. Regard Bruno. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] overloading function StrPLCopy
You have troubled me seriously, so I have dug in the compiler source. It appears that when parsing the source, Currency constants are cast to type BestReal (EXTENDED on I386) before being converted to the 8 byte currency written to the PPU or EXE or whatever is done. The combination of these steps DO USE FPU instructions on the I386, the compiler does not use SysUtils.StrToCurr to create the 8 bytes currency. As a bean counter, the point that was really scaring me was whether additions and subtractions of Currency's with Currency's would use the FPU. It appears that the generated (ASM) code actually uses Int64 arithmetic's for these 2 operations. Ouf... I run FPC 2.6.4 on WinXP machine with an Intel Core 2 CPU 6400 @2.13 GHz s Here after a program that should test if the compiler is run on a problematic CPU == program test_Currency_loop; var c:currency; cAsInt:Int64; // cAsInt64:Int64 absolute c; ix:integer; begin c:=92233720368547; cAsInt:=92233720368547; if Pint64(@c)^cAsInt then WriteLn('Problematic CPU for Compiler'); // FPU error on machine running the compiler Dbg stop point writeln(c); for ix:=1 to 9 do begin c:=c+0.0001; writeln(c); end; readln; end. == To test : 1-Compile and run on your XP machine. Copy the .EXE to your W98 machine and run it. See the results. 2-Compile and run on your Win98 machine. Copy the W98 .EXE to your XP machine and run it. See the results. I pop my stack and go back to what I was working on. Regards, Bruno ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Currency constant wrongly stored in generated EXE ? was: Re: Inconsistent results currency - extended ?
My point N°2 regarding potential FPU difference was only concerning instruction line e:=c; = I have absolutely no idea of how the compiler does translate Currency constant to code, sorry. May be it uses the FPU when translating from String representation to assembler value, but I have absolutely no idea where that would be done in the compiler. Anyway, it may be possible that the compiler uses StrToCurr or something similar. var cAsString:string; . . cAsString:=CurrToStr(c); c:=StrToCurr(cAsString). { == Check after here on W98 / XP and look for differences on value c. That uses an FPU instruction fistpll that look as causing some trouble to other projects (Non FPC) } . . Regards, Bruno Note : I'm interested to know what you discover since I like using Currency's var. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Inconsistent results currency - extended ?
Tested with FPC 2.6.4 . LacaK are you sure you compile with the same version. To me everything looks fine. program test_Currency; {$mode objfpc}{$H+} uses {$IFDEF UNIX}{$IFDEF UseCThreads} cthreads, {$ENDIF}{$ENDIF} SysUtils; var s: string; c: currency; e: extended; d: double; i64: int64; begin i64:=1 shl 63; c:=PCurrency(@i64)^; // Minimum representable currency d:=-92233720368547; e:=c; i64:=PInt64(@c)^; writeln('CW=', Get8087cw()); writeln('currency=', c); c:=-92233720368547.; // LacaK currency writeln('currency=', c); writeln('extended=', e); writeln('string=', currtostr(c)); writeln('int64=', i64); writeln('double=', d); readln; end. Gives me : CW=4978 currency=-9.223372036854775808E+14 - Ok to me currency=-9.22337203685470E+13 - Ok to me extended=-9.2233720368547758E+0014 string=-92233720368547. - Ok to me int64=-9223372036854775808 double=-9.22337203685480E+017 BrunoK ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal