57 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			57 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
|   | Multi-Threading Support in SRILM | ||
|  | --------------------------------------- | ||
|  | 
 | ||
|  | As of November, 2012 SRILM supports multi-threaded applications. This  | ||
|  | enhancment applies to the five libraries that comprise SRILM: libmisc,  | ||
|  | libdstruct, liboolm, libflm and liblattice.  Please note that this does not | ||
|  | imply that all API methods are thread-safe, but rather that it is possible to | ||
|  | perform independent SRILM tasks on multiple threads without interference or | ||
|  | instability. Some APIs that perform read-only calculations may be safe to call | ||
|  | on objects shared by multiple threads but in general this is not safe,  | ||
|  | particularly on APIs that mutate data structures not solely owned by the | ||
|  | current thread. We will attempt to document specific allowances and limitations | ||
|  | within this README and inline in the code. | ||
|  | 
 | ||
|  | SRILM uses TLS (thread-local storage) to support multi-threading. On non-Windows | ||
|  | platforms, TLS is provided by the pthreads library. On Windows we use the  | ||
|  | TlsAlloc family of OS calls. This approach covers most platforms. However, for | ||
|  | platforms that don't support TLS or applications that don't need multiple  | ||
|  | threads, SRILM can be compiled with -DNO_TLS=X to disable TLS in favor of  | ||
|  | traditional statics. | ||
|  | 
 | ||
|  | If you intend to use SRILM within short-lived threads (threads that will not | ||
|  | live as long as your process), it is necessary to free thread-local resources | ||
|  | prior to thread termination. This is achieved by calling the appropriate  | ||
|  | freeThread() method based on the SRILM modules used by your thread. For | ||
|  | instance, if your thread calls APIs in libflm, you must call  | ||
|  | FLMThreads::freeThread, which frees all thread-specific resources used by libflm | ||
|  | and its dependencies. If your thread only uses APIs in liboolm, you may call | ||
|  | LMThreads::freeThread. Note that libflm and liblattice don't depend on | ||
|  | each other, so if your thread utilizes APIs from both you must call both  | ||
|  | FLMThreads::freeThread and LatticeThreads::freeThread.  | ||
|  | 
 | ||
|  | Development Changes for SRILM Contributors | ||
|  | ------------------------------------------ | ||
|  | 
 | ||
|  | If you contribute to SRILM in a way that affects the 5 libraries, you must | ||
|  | refrain from using plain statics. Instead, use the various TLSW macros defined | ||
|  | in misc/src/TLSWrapper.h to declare a TLS Wrapper variable that imitates static | ||
|  | memory on a per-thread basis. For a basic example see the implementation of | ||
|  | Vocab::mapToLower in lm/src/Vocab.cc. There are various macros for declaring and | ||
|  | defining TLSW variables. In the event that NO_TLS is defined, the macros take | ||
|  | care of declaring equivalent static variables. When adding a new TLSW variable | ||
|  | you must insure that it will be freed by the freeThread method of the SRILM | ||
|  | module in which it resides. This is usually achieved by augmenting or adding a | ||
|  | static freeThread() method to the class that defines the TLSW variable.  | ||
|  | 
 | ||
|  | If you wish to use a TLSW varible inside of a template class you must take care | ||
|  | to define it outside the template definition. Otherwise, the variable will be | ||
|  | instantiated numerous times and you won't be able to free the memory associated | ||
|  | with the various instantiations. For an example of this, grep for writeBufferTLS | ||
|  | in the lm/src directory.  | ||
|  | 
 | ||
|  | Lastly, you must take care not to call any libc or other library functions that | ||
|  | are not thread-safe. We provide a thread-safe replacement for strerr in | ||
|  | misc/src/tserror.h as well as a thread-safe replacement for strtok in | ||
|  | MStringTokUtil.h. |