Monday, 29 February 2016

23 Feb

Task Groups

Can create a queue dedicated for one type of queue eg logic, thread runs throughs this
With queue/task group system we can make sure certain threads depend on other events and maintain their order
Eg when rendering is done, send event to animation (do not run before)

Can still be improved - system to create thread-specific queue
Could use CPU affinities (bind thread to a particular core)
Allow some tasks to have higher priority (useful for important tasks so they run first)
Can also batch up similar tasks (group them together)

Mutexes
Deals with shared data - shared data can cause issues
Mutex is a program object that allows multiple threads to access the same resource safely
Mutex can protect shared data by locking it
Offers exclusive, non-recursive ownership semantics (not repetitious)
Useful when one thread may read and another may write
This is known as being 'under concurrent read and writes'
Thread can wait for a mutex to unlock data or skip it if it is not vital
A mutex is a semaphore - object designed for concurrent usage
std::mutex mutexName; to create a mutex
mutexName.lock(); to lock the mutex and disallow other threads reading/writing
std::lock_guard<std::mutex>guard(mutexName); this creates a mutex that automatically unlocks after the thread has run (and is out of scope)
std::defer.lock to make sure the mutex doesn't lock automatically, an amount of time can be placed in

Atomics
Since mutexes are best used for low contention threads, we need something for high contention too
Atomics can be used
An operation type, it appears in all intents and purposes to occur instantaneously as a single operation
Must ensure your ordering to be able to use properly
Use fencing (border, threads) to achieve this
Fence tells compiler: you must use the order this is written in
std::atomic<int>intName; to create one.
Store (write) and load (read)
Use std::thread threadName (constructorName) to pass constructor and run as function pointer
All threads have a unique ID - can see this ID using std::this_thread::get_id();
this_thread:: always writes for current thread and stores in future

Could make threaded task instead(faster?) and store result of execution to std::future
std::async will always run immediately (no deferring)
Prefer using task - for the simple use of future to return value
Inside task an exception can be used to cancel (and close) that particular thread instead of the whole program, if something goes wrong
Can run out of threads, but not tasks
Threads can also cause slowdown if too many threads are called; tasks don't necessarily all run so any excess tasks won't cause any slowdown.

In summary: use threaded tasks

No comments:

Post a Comment