The Dark Secrets Of Faster Compilation With Delphi
In this post, we will explore various ways of improving Delphi applications and reducing development time. Moreover, we learn how to debug faster and smarter by using less known but valuable debugger features like groups, thread support, data breakpoints, and more. Faster Parallel Programs Compiler settings for effectively debug Breakpoints Passcount Debugging Multithreaded Programs Exceptions Hardware breakpoints and much more How to write fast parallel programs in Delphi? If you have been following CodeRage Online Developer Conferences, you know about FastMM4 and FastMM5. FastMM5 is a fast replacement memory manager for Embarcadero Delphi applications that scales well across multiple threads and CPU cores, is not prone to memory fragmentation, and supports shared memory without the use of external files. How can I achieve fast programs in Delphi using FastMM? With the newest update of FastMM that is FastMM5, you can achieve 15% higher performance on the single-threaded, and 30% higher on the multithreaded benchmarks. Reasons for slowdown If your Delphi application does not scale on a new multiprocessor, multicore, or multithreaded hardware, the obstacle might be lock contention in the memory allocator. Because threads are fighting for allocators. The obvious solution when the memory manager is slowing you down is to utilize fewer memory allocations that are either preload the memory and then reuse it without releasing it back to the system or change the algorithm in your code. You can find different methods to improve your application. Now it is demonstration time. We have an application here that do some calculations and we do that calculation with several workers to achieve higher performance procedure TForm1.Button1Click(Sender: TObject); begin SpeedTest := TSpeedTest.create(100); SpeedTest.NumWorkers := inpNumWorkers.Value; Button1.Enabled := false; Screen.Cursor := crHourGlass; Form1.Caption := ‘Time = ‘ + SpeedTest.Execute.ToString; SpeedTest.Free; Button1.Enabled := true; Screen.Cursor := crDefault; end; procedure TForm1.Button1Click(Sender: TObject); begin SpeedTest := TSpeedTest.create(100); SpeedTest.NumWorkers := inpNumWorkers.Value; Button1.Enabled := false; Screen.Cursor := crHourGlass; Form1.Caption := ‘Time = ‘ + SpeedTest.Execute.ToString; SpeedTest.Free; Button1.Enabled := true; Screen.Cursor := crDefault; end; As you can see, this is the driver code. It creates a test with some parameters, then sets the number of workers and executes the test with workers. function TSpeedTest.Execute: integer; var i: Integer; StopWatch: TStopwatch; begin Stopwatch := TStopwatch.Create; Stopwatch.Reset; Stopwatch.Start; if fNumWorkers > 1 then Parallel.For(0, fList.Count – 1) .NumTasks(fNumWorkers) .Execute( procedure(i: integer) begin fList[i].Execute; end) else for i := 0 to fList.Count – 1 do fList[i].Execute; Stopwatch.Stop; result := Stopwatch.ElapsedMilliseconds; end; 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 function TSpeedTest.Execute: integer; var i: Integer; StopWatch: TStopwatch; begin Stopwatch := TStopwatch.Create; Stopwatch.Reset; Stopwatch.Start; if fNumWorkers > 1 then Parallel.For(0, fList.Count – 1) .NumTasks(fNumWorkers) .Execute( procedure(i: integer) begin fList[i].Execute; end) else for i := 0 to fList.Count – 1 do fList[i].Execute; Stopwatch.Stop; result := Stopwatch.ElapsedMilliseconds; end; In the execute function, it just goes over the list. fList contains 100 items that we created in the constructor. As you can see, it goes over using parallel for loop if there is the worker number given. It is like we are doing some stress test on memory manager to benchmark. Here are the results with 1 and 2 workers: Now with 8 workers, you can see a little […]
