Question: Do I need a rocket science degree to deal with lcms2 in multithreading mode? What are ContextID and THR functions?
Actually it is a lot more simple. ContexID is nothing else that a void pointer that user can associate to profiles and/or transforms. It has no meaning. Is just a sort of used defined cargo that you can use on your convenience. lcms does nothing with that . It has no relationship with threads, but can be used to store information about the thread. Obviously you can ignore it if wish so. Then, by default this void pointer is set to NULL when creating the transform or opening the profiles. Additionally, if the programmer wish, there are functions which end with THR that can set the this to values other than NULL. In this way the threads, processes or wathever that are using the profiles and transforms can retrieve the value. It is just a way to store a 32 bit value along the handles.
On the other hand we have the 1-pixel cache. This is very convenient on slow interpolation methods when most of the pixels in the image are similar. Obviously, caching means the transform should store the result of last processed pixel, then in the case two threads are using the same transform at the same time, memory read/write operations on this value may clash and therefore you need some sort of semaphore. Ok, you can use a semaphore (the pthreads) or just get rid of the cache enterely. Please note that in some situations the cache is not used at all, i.e., on matrix-shaper to matrix-shaper 8 bit, it is actually faster to do always the computations, so the cache schema is discarded on this case. On CMYK trilinear, cache is being used as interpolation tends to be slow.
So, to answer your questions: If you use redundant transforms, you need not to worry about anything as each transform is using different cache. May be fast, but this is big a waste of memory. If you share the same transform on several threads, which is very efficient, you have either to disable the cache or to enable pthreads. I would reccomend to disable the cache, the performance gain when using multiple threads is huge, the performance gain when using cache is small. If you need more performance, just add more threads. You have not to use cmsCreateTransformTHR, this is just a way to add a user-defined variable to the handle, and finally cmsDoTransform does not have any ContexID, the error reports the ContextID associated with the transform being used. As a hint, ContexID are more useful when you want write a memory management plug-in to specialize memory mangement for multithreading, as the memory management pluging does recive ContextID when a memory operation is requested. The testebed application does use this feature to check memory consistency.
Showing posts with label Threads. Show all posts
Showing posts with label Threads. Show all posts
Friday, December 17, 2010
Saturday, June 27, 2009
Threads and cmsThreadID
One of the things lcms 2 is different to lcms is multithreading support. That is, indeed, a difficult feature. One may argue that just avoiding global variables should be enough to support multiple threads, but I think this is not necessarily true. Sometimes some global settings have to apply to all threads. On the other hand, it would be desirable for error handling and memory allocation to have some clues on which are the thread currently active or the environment where the current operation takes place.
So the solution I've found is the cmsThreadID type. That is just a void pointer.
Most of the high-level functions in lcms2 does have two forms. The first one is defaulting the ThreadID parameter to zero, which means "user don't care about threads". The second form allows to specify the ThreadID. This ID will be passed to memory allocation, error handler and plug-ins, so the user code may be smart enough to react differently on different threads. One example is to use different memory pools, which is useful, among others, when a given thread crashes and you want to recover gracefully.
Related functions :
cmsThreadID cmsGetProfileThreadID()
cmsThreadID cmsGetTransformThreadID()
And all functions with THR ending the function name, for example:
cmsHPROFILE cmsCreateRGBProfileTHR();
So the solution I've found is the cmsThreadID type. That is just a void pointer.
Most of the high-level functions in lcms2 does have two forms. The first one is defaulting the ThreadID parameter to zero, which means "user don't care about threads". The second form allows to specify the ThreadID. This ID will be passed to memory allocation, error handler and plug-ins, so the user code may be smart enough to react differently on different threads. One example is to use different memory pools, which is useful, among others, when a given thread crashes and you want to recover gracefully.
Related functions :
cmsThreadID cmsGetProfileThreadID()
cmsThreadID cmsGetTransformThreadID()
And all functions with THR ending the function name, for example:
cmsHPROFILE cmsCreateRGBProfileTHR();
Subscribe to:
Posts (Atom)