Jump to content

Steve Maughan

  • Content Count

  • Joined

  • Last visited

Community Reputation

7 Neutral

About Steve Maughan

  • Birthday September 23

Technical Information

  • Delphi-Version
    Delphi 10.2 Tokyo

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. 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
  2. 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
  3. 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
  4. 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
  5. Steve Maughan

    CDATA CSV Component

    FlexCel also read / writes CSV files
  6. HI Stefan, You may well be right. I need to test. Thanks, Steve
  7. 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
  8. 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
  9. 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
  10. 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
  11. 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
  12. 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 Synchronize2.zip
  13. 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
  14. 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 Synchronize.zip
  15. 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