-
Content Count
143 -
Joined
-
Last visited
Posts posted by Steve Maughan
-
-
Since the new MacOS compiler is based on LLVM I'd be interested to see any executable speed comparisons against Delphi Win 64 compiles. Won't the LLVM based compiler produce executables that run significantly faster? Or am I being too optimistic?
Steve
-
Apparently the new macOS Delphi compiler is based on the LLVM compiler. I wonder if future Delphi compilers for Win32 / Win64 will also be build on top of LLVM?
Would this improve the speed of the final executables?
Steve
-
1
-
-
19 hours ago, Remy Lebeau said:In VCL, the TBitmap.Canvas must be locked while using the TBitmap in a worker thread. The RTL keeps track of all GDI resources it allocates, and the main UI thread runs a routine periodically that frees GDI resources that are not locked. Which is very bad for TBitmap used in a worker thread. The alternative is to not use TBitmap at all, just use the Win32 API directly for all GDI operations in a worker thread.
Are you sure?
As I said above, in AlignMix I render a TBitmap.Canvas for each layer of a map using one worker thread per layer. It's rock solid, no crashes or resource issues when rendering.
Steve
-
Hi Stefan & Peter,
Thanks! I'm assuming most users will have a two or four core system. But power users may have 64 cores; it was really them I was thinking about. Truth is, I need to stop optimizing at this stage and focus on the actual algorithm.
Thanks again,
Steve
-
1
-
-
I'm considering ways of speeding up an algorithm. One option is to add parallel "for loops". I can certainly add a single parallel "for loop" and get a speedup. The algorithms effectively has nested "for loops" and I could also make the inner "for loops" parallel. Is this a advisable or are nested parallel "for loops" a big no-no? Or does it depend on the number of levels of nesting e.g. one inner parallel loop may be ok, but more would be bad?
Thanks,
Steve
-
In my app (AlignMix - a mapping package) we draw the map in layers (e.g. one layer may be road, another towns). Each layer is rendered by its own thread. We then "smush" all the layers together to get the final image. It works well, so clearly it is possible to draw on a TCanvas in a thread as long as no other thread is drawing on the same canvas.
Steve
-
4 hours ago, John Kouraklis said:FlexCel reads/writes only XLS files, doesn't it?
I will have another look again. Thx
FlexCel also read / writes CSV files
-
1
-
-
On 6/24/2019 at 8:11 AM, Stefan Glienke said:No way - a priority queue that balances when any value changes takes way more work than n-1 comparisons
I am pretty sure that nothing beats the following code performance nor simplicity wise:
for i := Low(data) to High(data) do begin // update data[i] if (i = 0) or (data[i] < min) then min := data[i]; end;
HI Stefan,
You may well be right. I need to test.
Thanks,
Steve
-
Thanks everyone.
It looks like a modified priority queue is the best solution. This keeps track of the minimum value and self balances when an internal node's value changes.
Cheers,
Steve
-
1 hour ago, Dany Marmur said:"Only interested in the min value". So why store anything BUT the min value?
Hi Dany,
Because the min before may change and not be the min before. I don't want to have to it's through to find a new minimum value.
Thanks,
Steve
-
Hi Stefan,
Each item's value changes slightly on each iteration. Note also, finding the min item may take more than one comparison per change (if the min item's value changes such that it's not now the min item).
Thanks,
Steve
-
Thanks Tim,
The algorithm updates the items' values 100k to 1 million times a second, so speed is important. Nevertheless, you might be right; I should probably keep it simple.
Steve
-
I have a small list of 200 items. Each item has a value. Over time, and with every iteration of my algorithm, each item's value is changed, but only slightly (e.g. ±2%). At any given time I'd like to quickly know the item with the smallest value (I don't care about any other value). What's the best data structure to accomplish this is a speedy manner?
I initially thought of a priority queue, but I'm changing the value of each item in the list.
Thanks,
Steve
-
I think I've solved it by using a TThreadList object as pseudo stack (FooList in the code below). This was something new for me. Previously I mistakenly thought "TThreadList" was a list of threads, whereas it's really a generic thread-safe list.
The thread-safe pop and push procedures are as follows:
function TForm1.PopFoo: TFoo; var xList: TList<TFoo>; begin xList := FooList.LockList; try if xList.Count > 0 then begin result := xList.Last; xList.Delete(xList.Count - 1); end else result := TFoo.Create; finally FooList.UnlockList; end; end; procedure TForm1.PushFoo(xFoo: TFoo); begin FooList.Add(xFoo); end;
In case anyone is interested I've attached the full source of the example project.
Thanks for the help,
Steve
-
2 minutes ago, David Heffernan said:It could still be related to the code that you have, which we don't have.
Anyway, it's a bad idea to force the code onto the main thread just to serialise it. Use a lock instead.
Hi David,
Thanks for the input but I've just provided a complete example. See attached above. You have all the code.
Based on your comment are you suggesting I mark the push and pop as Critical Sections? I haven't locked code before so please excuse my ignorance.
Thank again,
Steve
-
See attached for a simplified example . The procedure "ProcessSingleThreaded" works as expected, but the procedure "ProcessMultiThreaded" freezes the system:
procedure TForm1.ProcessMultiThreaded; var xBest: integer; i: integer; begin Screen.Cursor := crHourGlass; TParallel.&For(0, LoopSize - 1, procedure(j: integer) var xFoo: TFoo; begin //-- Get the Foo Object TThread.Synchronize(nil, procedure() begin xFoo := PopFoo; end); //-- Evaluate xFoo.Evaluate; //-- Push Back to the Stack TThread.Synchronize(nil, procedure() begin PushFoo(xFoo); end); end); xBest := 0; for i := 0 to FooList.Count - 1 do xBest := Max(xBest, FooList[i].BestValue); Form1.Caption := IntToStr(xBest); Screen.Cursor := crDefault; end;
Why is the TThread.Synchronize freezing the application?
All help appreciated,
Thanks,
Steve
-
Hi David,
PopNode and PushNode don't do anything special. I've listed the code below:
function TOptimizer.PopNode: TOptNode; begin if fNodeStack.Count > 0 then result := fNodeStack.Pop else begin result := TOptNode.Clone(fMasterNode); fNodeList.Add(result); end; end; procedure TOptimizer.PushNode(xNode: TOptNode); begin fNodeStack.Push(xNode); end;
All they do is either pop the Node if one already exists on the stack, or create a new node if the stack is empty. Clearly I don't want multiple threads popping and pushing at the same time. That's why the main thread should do all of the popping and pushing.
Thanks,
Steve
-
Hi Everyone,
This could well be a complete "noob" question as I'm not that experienced with the parallel library.
My objective is to utilize a parallel "for loop" in my optimization algorithm. Here's the code:
TParallel.&For(0, fCriteria.Population - 1, procedure(i: integer) var xNode: TOptNode; begin //-- Get the latest node TThread.Synchronize(nil, procedure begin xNode := PopNode; end); //-- Get the new centers xNode.GenerateNewCenters; //-- Evaluate new centers xNode.Evaluate; //-- Push the node back onto the stack TThread.Synchronize(nil, procedure begin PushNode(xNode); end); end);
Each iteration of the loop tests a new scenario (xNode.GenerateNewCenters) and stores the best one found (xNode.Evaluate). The TOptNode holds all the data that needs to be optimized. It's a large object and takes significant time to be created. So I've created a TStack of TOptNode object, and only create them when needed. I need to be able to "pop" the xNode objects off the stack and "push" them back on in a thread safe way. I would have thought the code above would work, instead it just freezes when it comes to the "for" loop.
What's the best way to "push" and "pop" in a thread safe manner inside of a parallel "for loop"?
Thanks,
Steve
-
I had the same problem. Here's the fix:
-
Has anyone had any success using Direct2D with multiple threads (i.e. multiple threads attempting to draw to the canvas at the same time)?
It seems possible according to this link:
https://docs.microsoft.com/en-us/windows/desktop/direct2d/multi-threaded-direct2d-apps
But I can't find anything Delphi specific information. Any links or sample code appreciated.
Thanks - Steve
-
Thanks - it's news to me!
-
There are quite a few Excel components available but I can't find any component to generate a PowerPoint presentation file. I realize I can possibly do this via OLE automation but that seems a little "flaky" to me. Does anyone know of a such PowerPoint component?
Thanks,
Steve
-
1 hour ago, Sherlock said:OMG, that website is a total turnoff.
Sorry 4 the OT.
It's one of Joe Hecht's sites. He has a few and they all look the same. I gave him some similar honest feedback over on Google+ a few years' ago. He agreed, but nothing seems to have changed. It's a pity since I'm sure the components are decent. It would take no more than two days to replace these sites with a good WordPress theme.
-
1
-
-
1 hour ago, Arnaud Bouchez said:Look into our OpenSource https://github.com/synopse/SynPDF project.
It is free, fast, creates small PDF, and you can draw your content using a regular VCL TCanvas: the same code could be used on screen and for the PDF.
Also note that there is no "resolution" in PDF, which is uses floating-point coordinates for its vectorial drawings.
If you generate from a TCanvas, your code will use integers, so here you may need to tune the resolution - just like with any VCL code.Interesting!! I'll take a closer look.
Thanks,
Steve
Any Benchmarks Comparing Executable Speeds for MacOS 64 vs Win 64?
in RTL and Delphi Object Pascal
Posted
Hi David,
I'm certainly not an expert in this field. Over the years I've seen various speed benchmarks that suggest Delphi's Windows compiler produces executables that are significantly slower than those produced by the top C++ compilers (e.g. Intel). In the chess world (where I am an expert) the rule of thumb is a Delphi version of a chess engine will run about 30% slower than the C++ equivalent code bases (Critter is the engine that was developed in two parallel code bases).
Let's face it, there doesn't seem to have been any work done on optimizing the code created by the Delphi compiler in the last 20 years. I'm just hoping the new backend will be better.
Thanks,
Steve