Advanced Multi-Threaded Development Overview
Explore the challenges and tips for developing multi-threaded applications in a workshop conducted by Jarrod Hollingworth in Melbourne. Learn about thread safety, Delphi Parallel Programming Library, and delve into low-level thread details. Dive into parallel programming with XE7+ and discover TParallel class functions for efficient multi-threaded execution. Gain insights into x86 Assembly and operations for optimizing CPU performance.
- Multi-Threaded Development
- Jarrod Hollingworth
- Thread Safety
- Delphi Programming
- Parallel Programming
Download Presentation
Please find below an Image/Link to download the presentation.
The content on the website is provided AS IS for your information and personal use only. It may not be sold, licensed, or shared on other websites without obtaining consent from the author. Download presentation by click this link. If you encounter any issues during the download, it is possible that the publisher has removed the file from their server.
E N D
Presentation Transcript
More! Multi-threaded Development Jarrod Hollingworth ADUG Melbourne, June 2018
Overview Threads Delphi Parallel Programming Library Thread Safety Challenges & Tips
Threads >= 1 per process Different CPUs in same process Share process resources (heap memory, globals, file handles) Own stack, program counter, registers Controlled by OS (time slice/wait, paused, resumed) Switched at any time Low level details are important
Parallel Programming Library XE7+, cross-platform System.Threading Based on TThread TParallel For loop, demo Basic thread safety Bonus demo: Conway s game of life TTask Running tasks, demo: Parallel Squares Waiting for task, demo Joins, futures, demo
TParallel class function For( LowInclusive: Integer; HighInclusive: Integer; IteratorEvent: TProc<Integer, TLoopState>; Sender: TObject; Stride: Integer; Pool: TThreadPool): TLoopResult; (30 overloads: optional parameters, anonymous methods/procedure of object, ) Iterations are run in parallel. Returns once all iterations are complete. TLoopState procedure Stop; procedure Break; property Stopped: Boolean; property Faulted: Boolean; TLoopResult property Completed: Boolean; property LowestBreakIteration: Integer; class function Join(const Procs: array of TProc; Pool: TThreadPool): ITask; (several overloads) Procedures are run in parallel. Returns once all procedures are complete.
x86 Assembly: total := total + 1; CPU1: CPU2: total mov edx,[eax+$0c] total inc edx mov [eax+$0c],edx total mov edx,[eax+$0c] inc edx mov [eax+$0c],edx total
x86 Operations: Inc(total); ASM: inc dword ptr [eax] CPU: Total Op.load temp_reg, [eax] Op.inc temp_reg Op.store [eax], temp_reg total
x86 Operations: Inc(total); ASM: inc dword ptr [eax] CPU2: CPU1: Op.load temp_reg, [eax] Op.inc temp_reg Op.store [eax], temp_reg Op.load temp_reg, [eax] Op.inc temp_reg Op.store [eax], temp_reg
TTask TTask class function Create/Run(Sender: TObject; Proc: TProc; APool: TThreadPool): ITask; class function WaitForAll(Tasks: array of ITask; Timeout: LongWord): Boolean; class function WaitForAny(Tasks: array of ITask; Timeout: LongWord): Integer; class function Future<T>(Sender: TObject; Func: TFunc<T>): IFuture<T>; ITask function Start: ITask; property Status: TTaskStatus; function Wait(Timeout: LongWord): Boolean; procedure Cancel; TTaskStatus Created, WaitingToRun, Running, Completed, WaitingForChildren, Canceled, Exception IFuture<T> property Value: T
TThreadPool TParallel.For/Join( , ThreadPool: ThreadPool) TTask.Create/Run( , ThreadPool: ThreadPool) TThreadPool is self-tuning based on # CPU cores and load Cannot free until all tasks are complete SetMaxWorkerThreads(Value: Integer) >= # CPU cores SetMinWorkerThreads(Value : Integer) <= MaxWorkerThreads Note: No guarantees. For total control use TThread.
Thread Safety Thread local variables (global storage) threadvar class threadvar Co-ordination & communication between threads (SyncObjs) TThread.Synchronize TThread.Queue (SyncObjs) TEvent.WaitFor(Timeout)/SetEvent/ResetEvent (Windows) PostMessage/SendMessage(Handle) (Windows) PostThreadMessage(ThreadId) Shared flag/data/queue, shared memory (inter-process), (immediate) (when main thread idle)
Thread Safety cont. Locking shared data/resource (SyncObjs) TCriticalSection.Acquire/Release/TryEnter (System) TMonitor.Enter(Obj, Timeout)/Exit/TryEnter: Boolean (SysUtils) TMultiReadExclusiveWriteSynchronizer BeginRead/EndRead/BeginWrite/EndWrite (SyncObjs) TSemaphore Create(InitialCount, AMaximumCount: Integer; Name: string) Acquire/Release(Count) (SyncObjs) TMutex.Create(Name: string)/Acquire/Release Atomic operations (SyncObjs) TInterlocked.Increment/Decrement/Add/Exchange/ (RTL) AtomicIncrement/ (Windows) InterlockedIncrement Fast Fast-ish, timeout Faster Slow, inter-process Slow, inter-process
Challenges & Tips Using the VCL/FMX & RTL Performance (different constraints, self tuning) Deadlocks (multiple locks, non re-entrant locks, use timeouts) Unhandled exceptions Testing (every computer/device and every run will be different) Stopping (or not) threads (notify, auto free, TerminateThread) Debugging (thread status, naming threads, switching threads) TThread.NameThreadForDebugging(Name: string)
Simple communication design Main thread Manager thread Data (locked) Job list UI Update Dispatch Synchronize/Queue/PostMessage Worker thread Worker thread Worker thread
Resources Book: Delphi High Performance - Primo Gabrijel i Wiki: http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Using_the_Parallel_Programming_Library Introduction video: https://youtu.be/x8S5b0peu7U Advanced techniques: http://web.archive.org/web/20120423060358/http://www.eonclash.com/Tutorials/Multithreading/ MartinHarvey1.1/ToC.html Demos: Conway s Life (TParallel.For) https://sourceforge.net/p/radstudiodemos/code/HEAD/tree/branches/RADStudio_Tokyo/Object%20 Pascal/RTL/Parallel%20Library/ Delphi Academy (Parallel Squares, TTask, Future) http://cc.embarcadero.com/Item/30754