-
Content Count
1428 -
Joined
-
Last visited
-
Days Won
141
Everything posted by Stefan Glienke
-
At least not if they promote that developer to PM
-
Delphi on Surface Pro with Qualcomm CPU?
Stefan Glienke replied to PeterPanettone's topic in Windows API
You might have misunderstood my sentence because obviously I was referring to any Delphi compiler that might target ARM - have you looked into the JIRA reports I linked? -
What are the performance profilers for Delphi 12?
Stefan Glienke replied to dmitrybv's topic in General Help
I'll take that opportunity and talk about it for an entire session at the Delphi Day and the Delphi Summit (the schedule still lists me talking about spring4d but for once I pass on that topic) đ -
Delphi on Surface Pro with Qualcomm CPU?
Stefan Glienke replied to PeterPanettone's topic in Windows API
Given the current issues regarding optimization that all LLVM-based Delphi compilers (that is all but the two Windows ones) have I am tempted to say that an x86 or x64 binary using the emulation layer might be faster than what a compiler that directly targets ARM would produce today. There are multiple reports about this and it boils down to "need to migrate to a newer LLVM version" which we have been told for years now - since recently the C++ Builder side was migrated to a recent LLVM version I hope that now the Delphi side gets addressed. https://quality.embarcadero.com/browse/RSP-9922 https://quality.embarcadero.com/browse/RSP-17724 https://quality.embarcadero.com/browse/RSP-25754 https://quality.embarcadero.com/browse/RSP-28006 -
FYI: Stumbled upon interesting ASM optimization trick LLVm can do (most likely others also)
Stefan Glienke replied to Tommi Prami's topic in Algorithms, Data Structures and Class Design
There are multiple considerations - I don't know what compiler version, target, and option he was using to conclude that it will use a lea rather than shift - at least with -O3 it will use shift for multiplications by 4 and 8 although lea would also be applicable - for mul by 2 most likely add is being emitted because that is just the smaller instruction. Another consideration is if the value is needed further - for example, x * 7 is implemented as x * 8 - x - and here it cannot use shift for the * 8 because it needs the original value of x to subtract, therefor it uses lea to store the result in another register and subtract the original register from it. Regarding the LEA instruction - I just remembered that I also reported that it should utilize this instruction when doing pointer math - see https://quality.embarcadero.com/browse/RSP-34820 -
FYI: Stumbled upon interesting ASM optimization trick LLVm can do (most likely others also)
Stefan Glienke replied to Tommi Prami's topic in Algorithms, Data Structures and Class Design
Interestingly the Delphi compiler did some optimization for multiplication by const for quite a while but it was weird and not very well - see https://quality.embarcadero.com/browse/RSP-38636. Unfortunately, when implementing this someone missed looking into the instruction timings of imul vs the replacements and so we got a degradation in some cases - see https://embt.atlassian.net/servicedesk/customer/portal/1/RSS-1011. -
What do you think of "Local Global variables"
Stefan Glienke replied to Tommi Prami's topic in RTL and Delphi Object Pascal
I've seen this mentioned before yet I never found this to be true - at least not in recent (past decade) Delphi versions. -
It looks to be fixed, but the Grep Search window is too small - HighDPI with 175%:
-
What do you think of "Local Global variables"
Stefan Glienke replied to Tommi Prami's topic in RTL and Delphi Object Pascal
While I at times use local routines I avoid accessing outer scope local variables like the plaque because it usually generates quite a huge and often unnecessary stack frame. -
Spring4d has an optimized version for XXH32 that is being used for the hashtables (dictionary and co) - see https://bitbucket.org/sglienke/spring4d/src/2dbce92195d699d51fc99dd226c4698748ec8ef9/Source/Base/Spring.Hash.pas#lines-46 Since all other versions in that family have a larger width and the hashcode in hashtables is typically 32bit (larger would only be worth once you have more than 2^30 items in it) I did not bother to implement the others as well (also XXH3 is a bit more complicated, XXH32 is quite simple actually) Also since the architecture of Spring4d 2.0 is pluggable you can replace it with your own hash function if anyone wants to come up with a faster one (I tried for example one from mormot2) - see https://bitbucket.org/sglienke/spring4d/src/2dbce92195d699d51fc99dd226c4698748ec8ef9/Source/Base/Spring.Comparers.pas#lines-87 Keep in mind though that the usecase in Spring4d is for hashtables - which means these hash functions typically don't hash gigabytes of data as in other use cases. Nevertheless, the faster the better. As for a Delphi wrapper for the original C++ implementation -see https://github.com/YWtheGod/XXHASH4Delphi
-
In rev 4252 there is a bug with the procedure list window on high dpi (possibly others? I did not test), it grows every time it's being opened. Edit: Sorry, should have gone into this thread:
-
How to patch a constructor?
Stefan Glienke replied to pyscripter's topic in RTL and Delphi Object Pascal
You don't want to do that - try solving your issue in AfterConstruction or otherwise. Code generated for constructors is more than meets the eye - replicating that without mistakes can be quite the endeavor. -
Delphi and "Use only memory safe languages"
Stefan Glienke replied to Die HollÀnder's topic in General Help
And unless they are implemented as thick 2-tier clients directly accessing some shared database they probably talk to some backend code where the interop with other systems is implemented. But let me make a slight correction about the particular Delphi situation: I know some people successfully build mobile apps but the majority are Windows (and some Mac OS) desktop applications I am also leaving out all the web stuff because Delphi does not play a significant role in that area (yes, I know about the various frameworks for doing web stuff with Delphi), and depending on what technology is used most of it is backend code. There has to be some reason why some recently very famous programming languages don't have some easy-to-use UI frameworks - either because they run almost everywhere including your toaster which makes it hard to provide some all-in-one solution (how often have UI frameworks tried that already?) or because it's code that does not require some rich UI. -
Delphi and "Use only memory safe languages"
Stefan Glienke replied to Die HollÀnder's topic in General Help
Why are Delphi developers so obsessed with doing GUI - I assume most software that operates the world is non-GUI stuff. And I also believe that this is typically the software that should be rock solid. The code that crashed Ariane 5 or caused security vulnerabilities in the recent past was hardly some GUI application. And Delphi code is only comparably fast with other languages that are top-tier in that category when you write it in a non-idiomatic way (i.e. pointers) - read some mormot Code if you don't believe me. Just one example: In other languages it does not matter if you are using some indexed-based loop (if that is even allowed) or some for-in/for-each loop - the compiler there knows its stuff and turns it into the fastest code possible while not sacrificing any safety. Sometimes the performance is even better when you are using built-in functions because internally the runtime and/or compiler devs did some incredible work optimizing stuff. Here is just one of the many examples of .NET 7. In Delphi, you almost always pay a cost for every abstraction although the compiler could make it zero-cost - one of the major tasks of modern compilers: enable the developer to write idiomatic and descriptive/declarative code without sacrificing performance. -
How know interface GUID from generic anonymous function using RTTI
Stefan Glienke replied to jairgza's topic in Algorithms, Data Structures and Class Design
That code only works for Delphi 10.2 and later - the proper way would be to simply write GUID := TypeData.Guid; -
Set enum property with TRttiProperty from string
Stefan Glienke replied to Tommi Prami's topic in RTL and Delphi Object Pascal
TValue has no implicit casting rule for integer -> enum - thus it raises the invalid cast exception because you are passing an Integer to SetValue which gets implicit put into a TValue which gets transported further. It later does a type/cast check against the actual type of the property and fails. See TValue.Cast or TValue.TryCast and the Conversions matrix for more details. I mentioned this many times: TValue is not Variant - it only supports implicit type casts that also the language supports and Integer to Enum type and vice versa is not directly assignable. procedure SetEnumProp(Instance: TObject; const PropName: string; const Value: string); var c: TRttiContext; t: TRttiType; p: TRttiProperty; typInfo: PTypeInfo; enumValue: Integer; v: TValue; begin t := c.GetType(Instance.ClassInfo); p := t.GetProperty(PropName); typInfo := p.PropertyType.Handle; enumValue := GetEnumValue(typInfo, Value); v := TValue.FromOrdinal(typInfo, enumValue); p.SetValue(Instance, v); end; -
Delphi and "Use only memory safe languages"
Stefan Glienke replied to Die HollÀnder's topic in General Help
This is why many modern and widely used languages have settled on using garbage collection (an automatic memory reclamation system) - because then the runtime deals with that and not the developer. -
Delphi 12 messing up with test project's DPR when using TestInsight and DUnitX
Stefan Glienke replied to John R.'s topic in Delphi IDE and APIs
My general advice to this is usually to move any conditional unit usage to its own unit and then only reference that unit in the dpr. Unfortunately, that is not some practice the DUnitX Expert is using. It would possibly also reduce the duplicated code generated for the dpr main every time. -
Delphi should let me use a const array reference as a constant
Stefan Glienke replied to PiedSoftware's topic in RTL and Delphi Object Pascal
Imagine you could write this code in Delphi: var i: Integer = 42; begin const j = i; Writeln(j); end. Oh, wait, you can. Too bad that the syntax is not really clean as it mimics the const declaration using the equal sign while it really is what other languages call immutable variable and thus should have used the assign operator but people with even less expertise in programming language design than me disagreed. -
IntToStr algorithm (Interesting read)
Stefan Glienke replied to Tommi Prami's topic in Algorithms, Data Structures and Class Design
Unless you show the benchmark code any results you mention are pointless because there can be so many things in the benchmark that lead to bias. You could for example run IntToStr in a loop and this will lead to using the same already allocated string over and over. -
However, it might not be permitted to do so in corporate environments.
-
Unsafe code 'String index to var param'
Stefan Glienke replied to JonRobertson's topic in RTL and Delphi Object Pascal
See https://stackoverflow.com/a/37688891/587106 -
I did not read all of it but here is a bit of information on that subject.
-
Differences in microbenchmarks can have all kinds of reasons (*) - when talking about the performance of single instructions you never estimate them from some possibly flawed microbenchmark but consult the instruction timings table (search for CVT(T)SS2SI) - the fact that truncate and non-truncate are always listed together makes it obvious that they perform exactly the same. (*) code alignment or address of the measured functions being one of the many reasons that can easily make some small or significant differences in the results All these tiny gotchas are the reason why many people don't like microbenchmarks. They are one tool for measuring but don't tell the ultimate truth - especially when it comes down to only a few instructions. That being said here are the results from an i5-13600K: x86 ----------------------------------------------------------------------------- Benchmark Time CPU Iterations ----------------------------------------------------------------------------- FastTrunc/Trunc:10910016 5585 ms 3703 ms 1 FastTrunc/FastTrunc_SSE2:10910032 2081 ms 1234 ms 1 FastTrunc/FastTrunc_SSE41:10910120 2158 ms 1047 ms 1 FastTrunc/SlowTrunc_SSE2:10910048 4193 ms 2641 ms 1 x64 ----------------------------------------------------------------------------- Benchmark Time CPU Iterations ----------------------------------------------------------------------------- FastTrunc/Trunc:12750304 5793 ms 3750 ms 1 FastTrunc/FastTrunc_SSE2:12750336 4775 ms 3656 ms 1 FastTrunc/FastTrunc_SSE41:12750432 6364 ms 4703 ms 1 FastTrunc/SlowTrunc_SSE2:12750352 4808 ms 2703 ms 1 Take these results with a grain of salt and keep in mind two things: - Spring.Benchmark still has some issues when running on Intels hybrid CPUs (12th and 13th gen) - I can trick a bit with setting Thread Affinity masks to run only on P-Cores but sometimes the times are a bit off - on x64 we might experience the behavior of implicitly converting Single to Double and back - I did not inspect the assembly code.
-
Isn't this all that is needed? function FastTrunc(Value: Single): Integer; asm {$IFDEF CPUX86} movss xmm0, Value {$ENDIF} cvttss2si eax, xmm0 end;