Commit e44903fb authored by lassoan's avatar lassoan

ENH: Added option to use TBB as SMP backend in VTK

TBB (Threading Building Blocks) provides tools for writing parallel C++ programs. VTK can use TBB to improve efficiency of execution of many filters.

Using TBB over default multi-threading (Sequential), multi-threaded image filter execution is typically improved by 20-30%. In cases where many threads are created (e.g., pipeline updates performed 10-100 per second, on an 8 or more core machine) and the computation load is very small, the speed may be improved by a factor of 10-20x. On some systems image reslicing performance is increased from 10fps to 130fps by switching from Sequential to TBB.

TBB is now enabled by default on Windows. Slicer with TBB has not been tested on Linux and MacOSX yet (probably building and packaging need some fixes).

git-svn-id: http://svn.slicer.org/Slicer4/trunk@27132 3bd1e089-480b-0410-8dfb-8563597acbee
parent 48dfadaa
......@@ -826,6 +826,7 @@ void qSlicerApplication::logApplicationInformation() const
<< "Operating system "
<< "Memory "
<< "CPU "
<< "VTK configuration "
<< "Developer mode enabled "
<< "Prefer executable CLI "
<< "Additional module paths ";
......@@ -846,11 +847,17 @@ void qSlicerApplication::logApplicationInformation() const
qPrintable(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")));
// Slicer version
qDebug("%s: %s (revision %s) %s - %s",
qDebug("%s: %s (revision %s) %s - %s %s",
qPrintable(titles.at(1).leftJustified(titleWidth, '.')),
Slicer_VERSION_FULL, qPrintable(this->repositoryRevision()),
qPrintable(this->platform()),
this->isInstalled() ? "installed" : "not installed");
this->isInstalled() ? "installed" : "not installed",
#ifdef _DEBUG
"debug"
#else
"release"
#endif
);
// Operating system
vtkNew<vtkSystemInformation> systemInfo;
......@@ -918,18 +925,27 @@ void qSlicerApplication::logApplicationInformation() const
systemInfo->GetModelName() ? systemInfo->GetModelName() : "unknown",
numberOfPhysicalCPU, numberOfLogicalCPU);
qDebug("%s: %s rendering, %s threading",
qPrintable(titles.at(5).leftJustified(titleWidth, '.')),
#ifdef Slicer_VTK_RENDERING_USE_OpenGL2_BACKEND
"OpenGL2",
#else
"OpenGL",
#endif
VTK_SMP_BACKEND);
QSettings settings;
// Developer mode enabled
bool developerModeEnabled = settings.value("Developer/DeveloperMode", false).toBool();
qDebug("%s: %s",
qPrintable(titles.at(5).leftJustified(titleWidth, '.')),
qPrintable(titles.at(6).leftJustified(titleWidth, '.')),
developerModeEnabled ? "yes" : "no");
// Prefer executable CLI
bool preferExecutableCli = settings.value("Modules/PreferExecutableCLI", Slicer_CLI_PREFER_EXECUTABLE_DEFAULT).toBool();
qDebug("%s: %s",
qPrintable(titles.at(6).leftJustified(titleWidth, '.')),
qPrintable(titles.at(7).leftJustified(titleWidth, '.')),
preferExecutableCli ? "yes" : "no");
// Additional module paths
......@@ -951,7 +967,7 @@ void qSlicerApplication::logApplicationInformation() const
}
qDebug("%s: %s",
qPrintable(titles.at(7).leftJustified(titleWidth, '.')),
qPrintable(titles.at(8).leftJustified(titleWidth, '.')),
additionalModulePaths.isEmpty() ? "(none)" : qPrintable(additionalModulePaths.join(", ")));
}
# -------------------------------------------------------------------------
# Find and install TBB Libs
# -------------------------------------------------------------------------
set(TBB_INSTALL_LIB_DIR "${Slicer_INSTALL_LIB_DIR}")
if(NOT EXISTS "${TBB_BIN_DIR}")
message(FATAL_ERROR "CMake variable TBB_BIN_DIR is set to a nonexistent directory: ${TBB_BIN_DIR}")
endif()
if(NOT EXISTS "${TBB_LIB_DIR}")
message(FATAL_ERROR "CMake variable TBB_LIB_DIR is set to a nonexistent directory: ${TBB_LIB_DIR}")
endif()
if(WIN32)
install(
FILES
${TBB_BIN_DIR}/tbb.dll
${TBB_BIN_DIR}/tbbmalloc.dll
${TBB_BIN_DIR}/tbbmalloc_proxy.dll
DESTINATION bin COMPONENT Runtime)
elseif(APPLE)
install(
FILES
${TBB_LIB_DIR}/libtbb.dylib
${TBB_LIB_DIR}/libtbbmalloc.dylib
${TBB_LIB_DIR}/libtbbmalloc_proxy.dylib
DESTINATION ${TBB_INSTALL_LIB_DIR} COMPONENT Runtime)
elseif(UNIX)
install(
FILES
${TBB_LIB_DIR}/libtbb.so.2
${TBB_LIB_DIR}/libtbbmalloc.so.2
${TBB_LIB_DIR}/libtbbmalloc_proxy.so.2
DESTINATION ${TBB_INSTALL_LIB_DIR} COMPONENT Runtime)
endif()
......@@ -86,6 +86,9 @@ if(NOT APPLE)
if(Slicer_USE_PYTHONQT_WITH_OPENSSL AND NOT Slicer_USE_SYSTEM_OpenSSL)
include(${Slicer_CMAKE_DIR}/SlicerBlockInstallOpenSSL.cmake)
endif()
if(Slicer_USE_TBB AND NOT Slicer_USE_SYSTEM_TBB)
include(${Slicer_CMAKE_DIR}/SlicerBlockInstallTBB.cmake)
endif()
if(Slicer_USE_QtTesting AND NOT Slicer_USE_SYSTEM_CTK)
include(${Slicer_CMAKE_DIR}/SlicerBlockInstallQtTesting.cmake)
endif()
......
......@@ -451,8 +451,28 @@ set(Slicer_VTK_RENDERING_BACKEND "${_backend}" CACHE STRING "Rendering backend."
mark_as_superbuild(Slicer_VTK_RENDERING_BACKEND)
set(Slicer_VTK_RENDERING_USE_${Slicer_VTK_RENDERING_BACKEND}_BACKEND 1)
# Slicer build is only tested with Sequential and TBB. OpenMP might work.
# Use TBB by default only on Windows, as it has not been tested on other platforms.
if(WIN32)
set(Slicer_DEFAULT_VTK_SMP_IMPLEMENTATION_TYPE "TBB")
else()
set(Slicer_DEFAULT_VTK_SMP_IMPLEMENTATION_TYPE "Sequential")
endif()
set(Slicer_VTK_SMP_IMPLEMENTATION_TYPE ${Slicer_DEFAULT_VTK_SMP_IMPLEMENTATION_TYPE}
CACHE STRING "Which multi-threaded parallelism implementation to use in VTK. Options are Sequential or TBB.")
set_property(CACHE Slicer_VTK_SMP_IMPLEMENTATION_TYPE
PROPERTY
STRINGS Sequential TBB)
mark_as_superbuild(Slicer_VTK_SMP_IMPLEMENTATION_TYPE)
if(${Slicer_VTK_SMP_IMPLEMENTATION_TYPE} STREQUAL "TBB")
set(Slicer_USE_TBB TRUE)
else()
set(Slicer_USE_TBB FALSE)
endif()
message(STATUS "Configuring VTK")
message(STATUS " Slicer_VTK_RENDERING_BACKEND is ${Slicer_VTK_RENDERING_BACKEND}")
message(STATUS " Slicer_VTK_SMP_IMPLEMENTATION_TYPE is ${Slicer_VTK_SMP_IMPLEMENTATION_TYPE}")
message(STATUS " Slicer_VTK_VERSION_MAJOR is ${Slicer_VTK_VERSION_MAJOR}")
set(Slicer_VTK_COMPONENTS
......
......@@ -173,6 +173,10 @@ if(Slicer_USE_PYTHONQT_WITH_TCL AND UNIX)
list(APPEND Slicer_DEPENDENCIES incrTcl)
endif()
if(Slicer_USE_TBB)
list(APPEND Slicer_DEPENDENCIES tbb)
endif()
#------------------------------------------------------------------------------
# Slicer_ADDITIONAL_DEPENDENCIES, EXTERNAL_PROJECT_ADDITIONAL_DIR
#------------------------------------------------------------------------------
......
......@@ -6,6 +6,9 @@ set(${proj}_DEPENDENCIES "zlib")
if (Slicer_USE_PYTHONQT)
list(APPEND ${proj}_DEPENDENCIES python)
endif()
if(Slicer_USE_TBB)
list(APPEND ${proj}_DEPENDENCIES tbb)
endif()
# Include dependent projects if any
ExternalProject_Include_Dependencies(${proj} PROJECT_VAR proj DEPENDS_VAR ${proj}_DEPENDENCIES)
......@@ -67,6 +70,19 @@ if((NOT DEFINED VTK_DIR OR NOT DEFINED VTK_SOURCE_DIR) AND NOT ${CMAKE_PROJECT_N
-DModule_vtkGUISupportQtOpenGL:BOOL=ON
)
endif()
if(Slicer_USE_TBB)
list(APPEND EXTERNAL_PROJECT_OPTIONAL_CMAKE_CACHE_ARGS
-DTBB_INCLUDE_DIR:PATH=${TBB_INCLUDE_DIR}
-DTBB_LIBRARY_DEBUG:FILEPATH=${TBB_LIBRARY_DEBUG}
-DTBB_LIBRARY_RELEASE:FILEPATH=${TBB_LIBRARY_RELEASE}
-DTBB_MALLOC_INCLUDE_DIR:PATH=${TBB_MALLOC_INCLUDE_DIR}
-DTBB_MALLOC_LIBRARY_DEBUG:FILEPATH=${TBB_MALLOC_LIBRARY_DEBUG}
-DTBB_MALLOC_LIBRARY_RELEASE:FILEPATH=${TBB_MALLOC_LIBRARY_RELEASE}
-DTBB_MALLOC_PROXY_INCLUDE_DIR:PATH=${TBB_MALLOC_PROXY_INCLUDE_DIR}
-DTBB_MALLOC_PROXY_LIBRARY_DEBUG:FILEPATH=${TBB_MALLOC_PROXY_LIBRARY_DEBUG}
-DTBB_MALLOC_PROXY_LIBRARY_RELEASE:FILEPATH=${TBB_MALLOC_PROXY_LIBRARY_RELEASE}
)
endif()
if(APPLE)
list(APPEND EXTERNAL_PROJECT_OPTIONAL_CMAKE_CACHE_ARGS
-DVTK_USE_CARBON:BOOL=OFF
......@@ -154,6 +170,7 @@ endif()
-DZLIB_LIBRARY:FILEPATH=${ZLIB_LIBRARY}
-DVTK_ENABLE_KITS:BOOL=${VTK_ENABLE_KITS}
-DVTK_RENDERING_BACKEND:STRING=${Slicer_VTK_RENDERING_BACKEND}
-DVTK_SMP_IMPLEMENTATION_TYPE:STRING=${Slicer_VTK_SMP_IMPLEMENTATION_TYPE}
${EXTERNAL_PROJECT_OPTIONAL_CMAKE_CACHE_ARGS}
INSTALL_COMMAND ""
DEPENDS
......
set(proj tbb)
if(${CMAKE_PROJECT_NAME}_USE_SYSTEM_${proj})
message(FATAL_ERROR "Enabling ${CMAKE_PROJECT_NAME}_USE_SYSTEM_${proj} is not supported!")
endif()
set(tbb_ver "2018_20171205oss")
if (WIN32)
set(tbb_file "tbb${tbb_ver}_win.zip")
#set(tbb_md5 "e7bbf293cdb5a50ca81347c80168956d")
elseif (APPLE)
set(tbb_file "tbb${tbb_ver}_osx.tgz")
#set(tbb_md5 "a767d7a8b375e6b054e44e2317d806b8")
else ()
set(tbb_file "tbb${tbb_ver}_lin_0.tgz")
#set(tbb_md5 "ab5df80a65adf423b14637a1f35814b2")
endif ()
#------------------------------------------------------------------------------
set(TBB_INSTALL_DIR "${CMAKE_BINARY_DIR}/${proj}-install")
ExternalProject_Message(${proj} "TBB_INSTALL_DIR:${TBB_INSTALL_DIR}")
ExternalProject_Add(${proj}
${${proj}_EP_ARGS}
URL https://www.paraview.org/files/dependencies/${tbb_file}
#URL_MD5 ${tbb_md5}
DOWNLOAD_DIR ${CMAKE_BINARY_DIR}
SOURCE_DIR ${TBB_INSTALL_DIR}
BUILD_IN_SOURCE 1
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
)
if(CMAKE_SIZEOF_VOID_P EQUAL 8) # 64-bit
set(tbb_archdir intel64)
else()
set(tbb_archdir ia32)
endif()
if (WIN32)
if (NOT MSVC_VERSION VERSION_GREATER 1500)
message(FATAL_ERROR "At least Visual Studio 10.0 is required")
elseif (NOT MSVC_VERSION VERSION_GREATER 1600)
set(tbb_vsdir vc10)
elseif (NOT MSVC_VERSION VERSION_GREATER 1700)
set(tbb_vsdir vc11)
elseif (NOT MSVC_VERSION VERSION_GREATER 1800)
set(tbb_vsdir vc12)
elseif (NOT MSVC_VERSION VERSION_GREATER 1900)
set(tbb_vsdir vc14)
elseif (tbb_enabled)
message(FATAL_ERROR "TBB does not support your Visual Studio compiler.")
endif ()
set(tbb_libdir lib/${tbb_archdir}/${tbb_vsdir})
set(tbb_bindir bin/${tbb_archdir}/${tbb_vsdir})
elseif (APPLE)
set(tbb_libdir "lib")
set(tbb_bindir "bin")
else ()
set(tbb_libdir "lib/${tbb_archdir}/gcc4.4")
set(tbb_bindir "bin/${tbb_archdir}/gcc4.4")
set(tbb_libsuffix "${CMAKE_SHARED_LIBRARY_SUFFIX}*")
endif ()
if (NOT tbb_libsuffix)
set(tbb_libsuffix ${CMAKE_SHARED_LIBRARY_SUFFIX})
if (WIN32)
set(tbb_libsuffix ${CMAKE_IMPORT_LIBRARY_SUFFIX})
endif ()
endif ()
# TODO: apply this patch
# if (UNIX AND NOT APPLE)
# superbuild_apply_patch(tbb gcc5x-warning-fix
# "Tell TBB about GCC 5.1 stdlib support")
# endif()
#------------------------------------------------------------------------------
set(TBB_INCLUDE_DIR "${TBB_INSTALL_DIR}/include")
set(TBB_LIBRARY_DEBUG "${TBB_INSTALL_DIR}/${tbb_libdir}/tbb_debug${tbb_libsuffix}")
set(TBB_LIBRARY_RELEASE "${TBB_INSTALL_DIR}/${tbb_libdir}/tbb${tbb_libsuffix}")
set(TBB_MALLOC_INCLUDE_DIR "${TBB_INSTALL_DIR}/include/tbb")
set(TBB_MALLOC_LIBRARY_DEBUG "${TBB_INSTALL_DIR}/${tbb_libdir}/tbbmalloc_debug${tbb_libsuffix}")
set(TBB_MALLOC_LIBRARY_RELEASE "${TBB_INSTALL_DIR}/${tbb_libdir}/tbbmalloc${tbb_libsuffix}")
set(TBB_MALLOC_PROXY_INCLUDE_DIR "${TBB_INSTALL_DIR}/include/tbb")
set(TBB_MALLOC_PROXY_LIBRARY_DEBUG "${TBB_INSTALL_DIR}/${tbb_libdir}/tbbmalloc_proxy_debug${tbb_libsuffix}")
set(TBB_MALLOC_PROXY_LIBRARY_RELEASE "${TBB_INSTALL_DIR}/${tbb_libdir}/tbbmalloc_proxy${tbb_libsuffix}")
set(TBB_BIN_DIR "${TBB_INSTALL_DIR}/${tbb_bindir}")
set(TBB_LIB_DIR "${TBB_INSTALL_DIR}/${tbb_libdir}")
mark_as_superbuild(
VARS
TBB_BIN_DIR:PATH
TBB_LIB_DIR:PATH
)
#-----------------------------------------------------------------------------
ExternalProject_GenerateProjectDescription_Step(${proj}
VERSION ${tbb_ver}
LICENSE_FILES "https://raw.githubusercontent.com/01org/tbb/tbb_2018/LICENSE"
)
#-----------------------------------------------------------------------------
# Launcher setting specific to build tree
set(${proj}_LIBRARY_PATHS_LAUNCHER_BUILD "${TBB_INSTALL_DIR}/${tbb_bindir}")
mark_as_superbuild(
VARS ${proj}_LIBRARY_PATHS_LAUNCHER_BUILD
LABELS "LIBRARY_PATHS_LAUNCHER_BUILD"
)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment