How to Statically Link to Tbb

Problems with statically linking Intel tbb

No, the singleton explanation refers to a single process, not the multiple processes case (though, it has some of the same issues with oversubscription and load balancing).

Dynamic linker makes sure there is only one global data section exists for the library and calls global constructors exactly once implementing singleton.

With statically linked TBB library, one can end up with multiple instances of TBB thread pool working in the same process simultaneously, which come from different components of an application. This causes the issue of over-subscription or even worse if somehow a memory or some object being allocated and registered in one instance of the scheduler gets used in another instance of the scheduler. This is especially easy to achieve because of thread-local storage that is heavily used by TBB scheduler. Each instance of the scheduler would use separate TLS breaking rules of nested parallelism up to deadlock and enabling memory leaks and segfaults because tasks allocated in one scheduler might end up being returned to another scheduler. Thus, this situation might not be obvious for developers who don't even intend to pass objects between module boundaries.

Sometimes, such a situation happens even with dynamic linkage when e.g. TBB shared library is renamed for one of application components. TBB team is working to solve this issue.

Linking to TBB libraries with CMake

Inspired by @AlexReinking answer, here is the final implementation:

    project(my-cpp-service VERSION 0.1.0)

# Equivalent to command-line option of `-DCMAKE_PREFIX_PATH=...`
list(APPEND CMAKE_MODULE_PATH "deps/tbb/cmake/")

find_package(TBB REQUIRED)

add_executable(${PROJECT_NAME}
src/main.cpp
)

target_link_libraries(${PROJECT_NAME} PUBLIC
TBB::tbb
)

does including execution require linking against tbb?

As @[n. 'pronouns' m.] rightly said, you may need libtbb in order to make your code work. You can download the Intel® oneAPI Base Toolkit which contains TBB as one of the components.
Link to download Intel® oneAPI Base Toolkit:
https://software.intel.com/content/www/us/en/develop/tools/oneapi/base-toolkit/download.html

Linking libraries statically

There are no easy ways, as far as I know.

There are some tools for "static linking" shared libraries:

  1. Statifier (open-source)
  2. Ermine (closed-source, paid)

You should probably ask about this, maybe you can bring shared libraries along and set the environment variable LD_LIBRARY_PATH to point to your shared libraries directory in a script before running your program.

As far as I remember Statifier didn't work for me. Ermine unlicensed gives some warnings and a 30-day limitation message, probably. So to distribute my thing across Linux systems with no admin rights I collected all needed shared libraries into a subdirectory, made a script that sets the env variable and launches my executable. And distributed it all as a zip.

spawning thread using static function using TBB in C++

It sounds like your question is really "how do I get a pointer to a static member function?"

C++ doesn't officially have a way to do that. However, according to the C++ FAQ (the Note in question 2), "pointers-to-static-member-functions are usually type-compatible with regular pointers-to-functions."

Your options are:

  1. Use a regular pointer to function, point it at your static member function, see if your compiler complains:

    int (*ptrFunction)(void*) = ThreadWrapper<Foo>::ThreadRoutineFunction;
  2. Do what the FAQ suggests, and declare your function extern "C" as well as static (you'll also have to declare the pointer to the function as extern "C", and you won't be able to overload the function):

    template <typename T> class ThreadWrapper {
    public:
    extern "C" static int ThreadRoutineFunction(void* param);
    };

    extern "C" int(*ptrCFunction)(void*) = ThreadWrapper<Foo>::ThreadRoutineFunction;
  3. Create an additional function that does nothing but call the static member function:

    template <typename T> int ThreadWrapperHelper(void* param)
    {
    return ThreadWrapper<T>::ThreadRoutineFunction(param);
    }

    int (*ptrFunction)(void*) = ThreadWrapperHelper<Foo>;

Linking with both static and dynamic libraries in MSVC

Typically when a library is made available as a dynamic library (.dll), it also comes with a .lib file to link against (as discussed in this question). This can be added to the project's list of inputs the same way that a static library is

Project Properties->Configuration Properties->Linker->Input->Additional Dependencies (in VS2008)

If a .lib is not available, then you'll have to load the .dll at runtime using Win32 API function LoadLibraryEx and then subsequent calls to GetProcAddress to get the addresses of the functions you need.



Related Topics



Leave a reply



Submit