

Kas Ob.
Members-
Content Count
538 -
Joined
-
Last visited
-
Days Won
9
Kas Ob. last won the day on April 13
Kas Ob. had the most liked content!
Community Reputation
138 ExcellentRecent Profile Visitors
The recent visitors block is disabled and is not being shown to other users.
-
Error when installing custom package - Module not found
Kas Ob. replied to JKNew's topic in Delphi IDE and APIs
PE Explorer can work but there is many other like https://www.mitec.cz/exe.html which unlike the outdated PE Explorer, does support 64bit. Now, Why Process Monitor is still better for this case ? If you are trying to investigate missing an import(s) then Process Monitor is useless, and investigating the import in the EXE using PE tools is better, but how to know if the library is there in the expected path and the one you should load or the Windows loader should load is the one you are expecting, here only tools like Process Monitor would help, in other words sometimes the path/location is the problem, and that about success of loading or failure, both are indicator, example runtime libraries built and installed by the IDE are not in the IDE bin path itself and not in the OS system path, and easily can be mixed between different IDEs causing failure of loading, due some file or path copy from place into another. -
Prg execution time problem in Delphi11.2 IDE and command line of a DLL function
Kas Ob. replied to lucarnet's topic in Delphi IDE and APIs
between same and worse. -
Prg execution time problem in Delphi11.2 IDE and command line of a DLL function
Kas Ob. replied to lucarnet's topic in Delphi IDE and APIs
Spent more than 4 hours on this, not because i already witnessed this many times, but just i wanted to refresh my frustration with this pile of sh** called Delphi 64bit debugger, Here i want to make few things clear 1) The Delphi debugger 32bit and 64bit does have parts are the least can be called masterpiece, so it is not useless in whole, but the smart people worked on it, either left and the debugger stuck with different people, who have least knowledge about the existing code should be or those who wrote that beautiful debugger loop, have no idea on what to do as next step. 2) I have XE8 so it might be different from modern IDEs, as Embarcadero in the last decade have the phrase "lets make Delphi great again" rephrased a little, and from readin they are focusing on LSP and making it great again, good luck with that ! considering they are just adding process and memory allocation, it is the exact thing that will be impossible to squeeze performance from, on the contrary it will be worse with every step in that direction. Now back to the subject, and most likely i will rant again about the debugger, @lucarnet you said it takes 2.5 minutes under debugging while it takes 1-2 seconds without a debugger, my CPU is Sandy Bridge i5-2500 from more that decade and half, the these times is strangely close, yes it takes between 2.5-5 minutes and i am talking about just loading the model, not even loading the recognizer. Out of intrigue i looked at this VOSK library and using their documentation i download the binaries with pyhon pip, so far so good, browsed the demos and liked this one https://github.com/alphacep/vosk-api/blob/master/c/test_vosk.c so translated the needed headers, and easier than that there is none const VOSK_LIBNAME = 'libvosk.dll'; type PVoskModel = Pointer; PVoskRecognizer = Pointer; function vosk_model_new(const model_path: PAnsiChar): PVoskModel; external VOSK_LIBNAME name 'vosk_model_new'; procedure vosk_model_free(model: PVoskModel); external VOSK_LIBNAME name 'vosk_model_free'; function vosk_recognizer_new(model: PVoskModel; sample_rate: Double): PVoskRecognizer; external VOSK_LIBNAME name 'vosk_recognizer_new'; procedure vosk_recognizer_free(rec: PVoskRecognizer); external VOSK_LIBNAME name 'vosk_recognizer_free'; function vosk_recognizer_accept_waveform(rec: PVoskRecognizer; const data: Pointer; len: Integer): Integer; external VOSK_LIBNAME name 'vosk_recognizer_accept_waveform'; function vosk_recognizer_result(rec: PVoskRecognizer): PAnsiChar; external VOSK_LIBNAME name 'vosk_recognizer_result'; function vosk_recognizer_partial_result(rec: PVoskRecognizer): PAnsiChar; external VOSK_LIBNAME name 'vosk_recognizer_partial_result'; function vosk_recognizer_final_result(rec: PVoskRecognizer): PAnsiChar; external VOSK_LIBNAME name 'vosk_recognizer_final_result'; great, now i need a model and wave file, so https://alphacephei.com/vosk/models and grabbed the first and smallest model 40mb from https://github.com/alphacep/vosk-api/tree/master/python/example grabbed the wave file 256kb so far so good build i the same demo and low and behold modelPath := 'vosk-model-small-en-us'; model := vosk_model_new(PAnsiChar(modelPath)); if model = nil then begin Log('Error loadin model'); Exit; end; This model loading takes minutes under debugger while takes something less then 3 minutes a little, and without the debugger it literally takes 400ms (milliseconds) it is 0.4 second ! So i am confirming your problem with debugger, later on this will write something. Now to your other problem, loading the model and recognizer doesn't even create a single background thread, as vosk_recognizer_accept_waveform kept failing and hugging the CPU, i couldn't make it work, but also didn't create threads ! So the threads in the log of yours is coming from your own miss using something somewhere, may be in handling wave file or microphone, fix these as these threads will only make the debugger even slower. Also the demo is somehow wrong in assuming and feeding 3200 bytes and didn't read the header right way to check for sample rate and channels every thing else, but it should work i guess, yet it didn't work on my device. Recommendation, Delphi debugger is useless and i am talking specifically about 64bit, it is wrong and doing wrong on so many levels 1) The demo and this library do allocate 4-5 chunks of memory each are 128mb, and will add more chunks for the recognizer and will increase but there is no memory leak, just huge amount of memory is needed, and it is expected. 2) The debugger utilize for unknown reason, well may be there was valid reasons 20 years ago, to have two processes to perform the debugging, but i can't justify having a sentinel process calling DebugBreak, WHY ? who knows. 3) Now comes the fun part, the debugger must be 64bit while the IDE 32bit so an IPC is due, great, so lets take one and never look back, so they choose TCP, TCP (WTF), even on loopback it is TCP packets, no shared memory ?! no no shared memory ! 4) Now the debugger perform ReadProcessMemory as like every debugger out there, but wait we mist do it differently, see since the dawn of computers half century ago there was pages and they are 4kb and on Windows an address is valid if the page is valid, so lets perform the reading on 512byte ! 5) 512bytes is somehow still better than 1 byte, so lets perform reading on 1 byte, we must not gave up, and in case we wrote the breakpoint by using WriteProcessMemory at single byte which is fine and justified, lets do all the breaks points to make sure and even the API is success, success means it does wrote the memory, we must be sure and read them all again , !! 6) OK we have the memory read in small chunks we need to ship them to the IDE and the IDE debugger, lets send them in 1,8,12,16 bytes, genius !, so hundred of thousands of send over TCP in the smallest way possible, notice TCP require ACK, so switching to UDP will enhance the throughput, we are against that, and still no shared memory ! 7) how to handle sockets in Turbo Pascal way over dialup modem, every IOCTLSocket (the successful ones) should be followed be WSAGetLastError for no freaking reason, and lets mix Select with WSAAsyncSelect to create an abomination, just to make sure, while the IDE and its UI will block for every packet, so the IDE should freeze showing it is busy, great ideas and great design. .. So many things to be angry about, as i can't be unbiased here, but the IPC between IDE and real debugging process is wrong and outdated, it can work and debug a 10 lines project, not a real life semi-heavy application. Now i am angry 😪 @lucarnet there is no way to debug such heavy memory usage application using very, yes very outdated debugger, the Delphi debugger, you should fix the threads creation as i mentioned above, as it is has nothing to do with VOSK library, and skip debugging on Delphi, use logging instead, i am guessing here, those thread are coming form your different library you are using to handle microphone or wave file reading. And good luck ! Ps: looking at the assembly generated for 64bit it is a sight to see NOP there between the instruction serving literally nothing, and even one of them was ducking up the alignment in the freaking loop, wow just wow. -
Prg execution time problem in Delphi11.2 IDE and command line of a DLL function
Kas Ob. replied to lucarnet's topic in Delphi IDE and APIs
I just remembered seeing a code or something were the the programmer tried to decode audio captured into image, so the audio is PCM and at minimum (standard minimum) and will be 8000 sample per second, and he was trying to spawn a thread for each sample to perform Fourier transformation on each and every sample, so his idea was to spawn 8000 thread per second at least, i think you are making a mistake close or similar to this, so in case these threads are yours then rethink again and find a working demo or the from documentation on how to feed the data the right way. -
Prg execution time problem in Delphi11.2 IDE and command line of a DLL function
Kas Ob. replied to lucarnet's topic in Delphi IDE and APIs
Don't know what is Vosk is and will not search the internet, one thing i can see is very wrong in your attached log file The amount of threads started and exited is huge and wrong, so 1) Either there is some setting your are missing to let such library utilize threading pool right, or you are calling the wrong model. 2) You are loading and unloading the library or part of it so may times ! Check these, because i don't believe a normal and tested library should use so much thread in such manner, that makes no sense at all. -
I didn't know about this and it is nice and looks accurate, though the usage of streams is little excessive instead of just accept memory buffers then add stream(s) as an overload, anyway the only two things the author missed are : 1) deriving TWebpImage from TGraphicControl instead of TGraphic. By changing the base and making the needed overrides, One can call something like this TPicture.RegisterFileFormat('WebP', 'Web Portable Graphics', TWebpImage); Allowing TPicture to support WebP out of the box, VCL will be able to handle WebP images, from TImage to glyphs on buttons. 2) add static objects linking as an option removing the need for the DLL.
-
No, you understand it right, just not Epsilon, that is annoying. Not sure about naming it Tolerance or tor though.. because somehow feels misleading too like epsilon, The use of Delta mostly comes form the word Distance and used as such. also Delta in general associated with difference between two values, and it is de facto the standard distance between points or values ( like |x-x0| = Dx , or |x,y| =Dxy ....), vectors (in geometry) etc May be Threshold, ComparisonThreshold, AcceptedDistance , MaxDifference, AllowedError, AllowedDistance ...
-
One last thing here, from the documentation Although i hate to do the multiplication and see it to some extent as wrong instead of division of the delta on the biggest, why this is not in the library (Math unit) as function ? that is the question.
-
That is personal point of view, i agree, but how many out there and here in this very forum knows that SameValue without Epsilon with return True for any value less than 1e-4=0.0001 even with 0, like comparing 0.000099 with zero will be True, also for bigger number should Epsilon go in decimal or will always be False, and how many knows how to estimate Epsilon the right way. Machine Epsilon should be incorporated check approximation, that is a fact, and the lack of documentation is disturbing to say the least, the main point here isn't this the job of the library (or the function) to do that in right and correct way ? Just food for thoughts. And yes should renamed to be Delta there.
-
Can't agree more, yet there is many cases when you can't predict the usage of a library or the user input, in real estate 1 square meter could be priced at $1000 or even $10000 even for small office at 33 square meter, so the fractal part worth non negligible value, in other cases the asset we need to process all the same is at million square meter, here the price could be not a problem but are the result have the same precision ? i know i sound like losing the subject !, Please bare with me a little, i will try to explain few things which many knows and many doesn't know, just to reach some points at the end. i will start with single float point, it is 32bit and we all know its structure and how it work, but i am writing about the things that are not very known ! lets look at the smallest number that single can have, and again i am talking about positive only here as the negative while they are less but ,, meh ,, it is just signal bit, anyway the 3 smallest numbers, and here pay attention i am going with normal and not subnormal ones, these are smaller a lot but they are different case, while both belongs to IEEE 754, the smallest one is 2^−126, i don't have calculator to get the decimal value because it will help here, so i am using online Wolfram Alpha 2^-126 = 1.1754943508222875079687365372222456778186655567720875215087517062784172594547271728515625 × 10^-38 but we are limited in precision and i need the decimal representation and singles has 24 precision so 2^-126 = 0.000000000000000000000011754943508222875079687365372222456778186655567720875215087517062784172594547271728515625 But this approximation and could have more puppies, i mean digits, yet we (computers and software) can't handle such precision out of the box so lets truncate it a little, we get the smallest three singles 0 0.000000000000000000000011754943508222875 | 0.000000000000000000000011754943782280733 | the step is 0.000000000000000000000000000273057858 again in these numbers i am taking normal not subnormal, the difference exist in the 1 on the left side and it affect precision, long story and irrelevant to this post. While the biggest numbers are 340282313029632462711731687303715884032.0 | 340282346638528859811704183484516925440.0 | the difference aka step here is 33408896097170127936.0 Infinity (overflow) the step plays crucial rule in float point, as it resize based on the exponent used, in other words we might add billions and yet the result will not change a bit ! Fun fact on side note, ULP is the official name for these adaptive steps and let see what happen when and where ULP is >= 1 ULP(x) = 2^(exp2(x)-23) , so for >=1 we have exp2(x) >= 23 , hence x >= 2^23 and this equal to 8388608 , Now to the eyes widening fun fact for any value for x where x >= 8388608 , we have x +1 = x , here x is single and might be better to be written 8388608.0 , yet i think the idea is received, if you do 8388608.0 + 1.0 then the result will be 8388608.0 !! with that fun fact at hand imagine using single or double, any float numbers to count puppies in a country, we will thing we increasing by one and will hit hard limit without any notice or problem. same if we are counting pairs of eyes of puppies the there is limit when the step by 2 will be neglected and lost. as for bigger numbers as shown above we might be adding millions or billions and losing money, that why banks and financial software should never use floating point and stick to fixed point. Now back to our non beloved puppies killer SameValue, and here my thoughts 1) It does use Epsilon in violation to what epsilon represent, there is Machine Epsilon mentioned above, but Epsilon generally in math used to describe small values no Deltas, yes in that context and as it implemented it should be named Delta, that name trigger my OCD. 2) SameValue calculate the Delta between singles not THE approximation for equality, not the sameness with tolerance, just Delta, so if you feed a number like 1000 then you might expect the close one at 1000.01 with %1 error tolerance, this Delta or Epsilon make no sense when the number is 1000 000 because it will be Delta and will compare between 1000 000 and 1000 000.01 , can you spot the different here ? we are using the same delta and changed the tolerance to %0.0001 , this goes up and down, and the only way to accommodate this factor is by adjusting the Delta (Epsilon for the SameValue) at runtime, while this can be ignored or pre-calculated for assertion, it is a must for runtime if you value your calculations and output precision. 3) the documentation fails to mention the delta usage and fail to warn about this very shortage. 4) The default value for error tolerance if we might call it for SameValue, is 1e-7*1000= 1e-4 = 0.0001 , for single type, this is useless when numbers goes in thousands or millions, but the real danger is for small numbers like the ones which are less than 0.0001 , they all are equal with SameValue ! 5) Rollo62 mentioned known the arena we staging and performing within, yet for a small office or room where 4x5 m we can use the same tolerance (we put it there like 0.01 for 1 cm) for the dimensions and the area and we still in control, but if we used the tolerance E=0.01 (1e-2) , with huge farm land with where 1000x1000m we have million squared meter and we are in different realm like the example in (2), notice for larger numbers above 8 millions and from above too, 1 meter tolerance is literally no sense operation. Now from these i can deduce this, SameValue is wrong, Anders asked if it is within its implementation, and yes it is but it has deceiving name, it should be called something CloseEnoughBy , and never should be used for testing equality or approximation of equality, it failed in documentation and failed in implementation to serve the sameness which it claim, as for its usage and how to use it right, then you have to calculate the correct and right Epsilon then provide it as parameter, rendering its usage merely compare the difference, aka within Delta. In my opinion SameValue should 1) deprecated, just kill it and warn who use it to refer to the documentation. 2) add a real, useful and correct alternative like SameValueEx or some other name. 3) Yes like Anders point to, the implementation should test first for 0 and NaN , in other words it should be right implemented, and this mean with the suggested formula it will be slower a lot, like a lot, but and as always correctness can't and must not be a point to discuss, the developer can and should seek alternative if it will be used in big/long tight loop, heck he can use SameValue 🙂 killing more puppies 😠4) The enhanced version could have multiplier (cofactor) for Epsilon instead of Epsilon, as it should be strictly using Machine Epsilon, the multiplier can serve better in implementation, example if you are calculating area then two singles involved hence we can adjust the positive only multiplier to adjust to the area, thus we have clearer and easier reach for the best error tolerance, and here i don't want to drive this of the road as multiplier from mathematically and statistically the correct way should be accurately adjusted, see, in case of 2d and area calculation there is many methods for error tolerance from CEP to Root Mean Square Error to .... but we talk singles and many of those doesn't apply on the single arithmetic operation itself those apply to the input values for the arithmetic operation and for the operation it self we are little more free, this is due the fact float point are approximations so we can just use a factor of 2 or you can go with sqrt(2) or even 10, this is up to the developer and the engineer of the formula/operation involved. Hope that was clear and somebody find it useful ! ps: more things came to mind now, where i saw many made such mistake, see, single can hold a large number like 340282346638528859811704183484516925440.0 and small number like subnormal 2^−149 = 0.00000000000000000000000000000000000000000000140129846432481707092372958328991613128026194187651577..... But it can't have 340282346638528859811704183484516925440.6 in fact the closest number to 340282346638528859811704183484516925440.0 is the one i listed above and it is far by 33408896097170127936.0 So be careful when and how you use float point and remember one thing float point is like ruler (exponential one) that slide up and down losing anything not in the range, well mostly it slide up only killing all creature including puppies standing behind the point. PS i made a mistake above and will not correct it, but will point to it here and too lazy to read and rewrite, i dont think this change a lot of the above though. I used ">=" instead of ">" in calculating ULP and this leads to mistakenly assuming adding one to 8388608.0 will result the same, while with ">" the needed exp will be 24 so 16777216, and here is the testing code procedure TestULPx; var A, B, C: Single; begin A := 8388608.0; B := 1.0; C := A + B; Writeln(C); A := 16777214.0; B := 1.0; C := A + B; Writeln(C); A := 16777215.0; B := 1.0; C := A + B; Writeln(C); A := 16777216.0; B := 1.0; C := A + B; Writeln(C); end; The output 8.38860900000000E+0006 1.67772150000000E+0007 1.67772160000000E+0007 1.67772160000000E+0007 // 16777216.0 is the threshold at 2^24 when adding one is lost, x+1=x
-
May be i missed, SameValue does work as documented, no word there. Yet it doesn't use the standardized value for the default Epsilon and it does that without documentation, its documentation should declare it use low(reduced) precision for comparison by default.
-
Well this is longer discussion and need scratching behind the ear, not from the puppies fleas but pretending thinking deeply The suggested formula above is the best one or lets say the most right one, but it is not adaptive with fixed error tolerance, adaptive one will be more complex and depend on the exponent part and scale with it, think about it, comparing numbers in billions makes the machine Epsilon very silly, so such epsilon (error tolerance) should be magnified a little to accommodate the fact these numbers and the need for their comparison is coming for arithmetic operations, so multiple mE by 10^n makes more sense.
-
The right way to do (the formula) at that very Wikipedia page, from https://en.wikipedia.org/wiki/Machine_epsilon#Relationship_to_absolute_relative_error the first line has the formula, and its proof, while the last line explain how to generalize it to Notice that the mentioned formula i suggested is the exact one but it use the max between x and y, unlike the Wikipedia listed formula, the reason is using the biggest one will increase the precision as the left side might fall beyond one machine epsilon step, using the biggest (max) hence it is the right way to do it, also the SameValue should be check the same value within best highest precision possible, so while we have defined and mathematically proven formula we should stick to the most standardized references, in other words it should utilize division instead of multiplication. This formula is not from yesterday... Digging more and consulting with Wikipedia sources i see what might be the origin of these numbers used in Math unit here from 1999 https://people.eecs.berkeley.edu/~demmel/cs267/lecture21/lecture21.html While the correct epsilon values should be For singles = 1.19e-07 and for doubles = 2.22e-16 Now comes to the formula from that page again we have
-
Right, yet the formula for the comparison should be MaxValue := Max(Abs(A), Abs(B)); if (Abs(A - B) / MaxValue) < Epsilon // Epsilon is the optional provided one or Machine Epsilon and the machine Epsilon should be For singles = 1.19e-07 and for doubles = 2.22e-16 These numbers are known and defined https://en.wikipedia.org/wiki/Machine_epsilon#Values_for_standard_hardware_arithmetics and not what Math unit define in the RTL as approximation to these, then for some unexplained reason multiplied by 1000 reducing precision 3 degree to kill 3 puppies at least ðŸ˜
-
Look at these cute puppies 0.96493138416 , look at them pawsitively ! SameValue will murder some of them as its error tolerance is fixed (not adaptive) and the comparison is .. meh .. it looks close (aka very far error tolerance), so some cute puppies and kittens will be missed by the world ðŸ˜