Как статически ссылаться на TBB? - PullRequest
18 голосов
/ 12 марта 2009

Как я могу статически связать библиотеки TBB Intel с моим приложением? Я знаю все предупреждения , такие как несправедливое распределение нагрузки планировщика, но мне не нужен планировщик, только контейнеры, так что все в порядке.

В любом случае, я знаю, что это можно сделать, хотя это недокументировано, однако я просто не могу найти способ сделать это прямо сейчас (хотя я видел это где-то раньше).

Так кто-нибудь знает или имеет какие-либо подсказки?

спасибо

Ответы [ 7 ]

11 голосов
/ 30 октября 2013

Настоятельно не рекомендуется:

Существует ли версия TBB, которая предоставляет статически связанные библиотеки?

TBB не предоставляется как статически связанная библиотека по следующим причинам *:

Большинство библиотек работают локально. Например, Intel (R) MKL FFT преобразует массив. Не имеет значения, сколько существует копий БПФ. Несколько копий и версий могут сосуществовать без труда. Но некоторые библиотеки управляют ресурсами всей программы, такими как память и процессоры. Например, сборщики мусора управляют распределением памяти между программами. Аналогично, TBB контролирует планирование задач в рамках программы. Чтобы эффективно выполнять свою работу, каждый из них должен быть одиночным; то есть иметь единственный экземпляр, который может координировать действия по всей программе. Если разрешить k экземпляров планировщика TBB в одной программе, то программных потоков будет в k раз больше, чем аппаратных потоков. Программа будет работать неэффективно, потому что машина будет переподписана с коэффициентом k, что приведет к большему переключению контекста, кэш-памяти и потреблению памяти. Кроме того, эффективная поддержка TBB для вложенного параллелизма будет сведена на нет, если вложенный параллелизм возникнет из-за вложенных вызовов различных планировщиков.

Наиболее практичным решением для создания синглтона всей программы является динамическая разделяемая библиотека, которая содержит синглтон. Конечно, если бы планировщики могли сотрудничать, нам не нужен был бы синглтон. Но это сотрудничество требует централизованного агента для общения; то есть синглтон!

На наше решение об исключении статически связываемой версии TBB сильно повлиял наш опыт OpenMP. Как и TBB, OpenMP также пытается составить расписание для всей программы. Однажды была предоставлена ​​статическая версия среды выполнения OpenMP, и она была постоянным источником проблем, возникающих из-за дублирующих планировщиков. Мы считаем, что лучше не повторять эту историю. В качестве косвенного доказательства обоснованности этих соображений можно указать на тот факт, что Microsoft Visual C ++ обеспечивает поддержку OpenMP только через динамические библиотеки.

Источник: http://www.threadingbuildingblocks.org/faq/11#sthash.t3BrizFQ.dpuf

8 голосов
/ 09 августа 2016

РЕДАКТИРОВАТЬ - Изменено для использования extra_inc. Спасибо, Джефф!

Сборка со следующим параметром:

make extra_inc=big_iron.inc

Статические библиотеки будут собраны. См. Предостережения в build/big_iron.inc.

4 голосов
/ 23 октября 2016

Сборка статических библиотек из источника

После получения исходного кода от https://www.threadingbuildingblocks.org/, построить TBB следующим образом:

make extra_inc=big_iron.inc

Если вам нужны дополнительные опции, то вместо этого соберите так:

make extra_inc=big_iron.inc <extra options>

Запуск нескольких программ TBB на узел

Если вы запускаете многопроцессорное приложение, например, при использовании MPI может потребоваться явная инициализация планировщика TBB с соответствующим количеством потоков, чтобы избежать переподписки.

Пример этого в большом приложении можно найти в https://github.com/m-a-d-n-e-s-s/madness/blob/master/src/madness/world/thread.cc.

Комментарий к документации

Эта функция была доступна в течение многих лет (по крайней мере, с 2013 года), хотя она не задокументирована по причинам, описанным в других ответах.

Историческая справка

Эта функция изначально была разработана, поскольку суперкомпьютеры IBM Blue Gene и Cray либо не поддерживали общие библиотеки, либо не работали при их использовании из-за отсутствия локально смонтированной файловой системы.

2 голосов
/ 05 июня 2017

Хотя это официально не одобрено командой TBB, возможно создать собственную статически связанную версию TBB с make extra_inc=big_iron.inc.

Я не тестировал его в Windows или MacOS, но в Linux он работал ( source ):

wget https://github.com/01org/tbb/archive/2017_U6.tar.gz
tar xzfv 2017_U6.tar.gz
cd tbb-2017_U6
make extra_inc=big_iron.inc

Сгенерированные файлы находятся в tbb-2017_U6/build/linux*release.

Когда вы связываете свое приложение со статической версией TBB:

  • Вызовите g ++ с помощью переключателя -static
  • Ссылка на tbb (-ltbb) и pthread (-lpthread)

В моем тесте мне также нужно было явно сослаться на все .o файлы из версии TBB, созданной вручную. В зависимости от вашего проекта, вам также может понадобиться передать -pthread в gcc.

Я создал игрушечный пример для документирования всех шагов в этом хранилище Github:

Он также содержит тестовый код, чтобы убедиться, что сгенерированный двоичный файл переносим в других дистрибутивах Linux.

2 голосов
/ 03 марта 2014

Использование версии с открытым исходным кодом:

После запуска "make tbb" , перейдите в папку build / linux_xxxxxxxx_release.

Затем запустите:

ar -r libtbb.a concurrent_hash_map.o concurrent_queue.o concurrent_vector.o 
dynamic_link.o itt_notify.o cache_aligned_allocator.o pipeline.o queuing_mutex.o 
queuing_rw_mutex.o reader_writer_lock.o spin_rw_mutex.o spin_mutex.o critical_section.o
task.o tbb_misc.o tbb_misc_ex.o mutex.o recursive_mutex.o condition_variable.o 
tbb_thread.o concurrent_monitor.o semaphore.o private_server.o rml_tbb.o 
task_group_context.o governor.o market.o arena.o scheduler.o observer_proxy.o 
tbb_statistics.o tbb_main.o concurrent_vector_v2.o concurrent_queue_v2.o 
spin_rw_mutex_v2.o task_v2.o

И вы должны получить libtbb.a в качестве вывода.

Обратите внимание, что ваша программа должна собираться как с "-ldl", так и с libtbb.a

1 голос
/ 29 октября 2009

К сожалению, это не представляется возможным: С сайта TBB. .
Одним из предложений на форуме Intel было скомпилировать его вручную, если вам действительно нужна статическая связь: Из форума Intel .

0 голосов
/ 01 февраля 2012

Просто свяжите файлы, я просто сделал это и работает. Вот файл SConscript. Есть две второстепенные вещи: символ с одинаковыми именами в tbb и tbbmalloc, которые я должен был предотвратить множественным определением, и я запретил использование ITT_NOTIFY, поскольку он создает другой символ с тем же именем в обеих библиотеках.

Import('g_CONFIGURATION')
import os
import SCutils
import utils

tbb_basedir = os.path.join(
    g_CONFIGURATION['basedir'],
    '3rd-party/tbb40_233oss/')

#print 'TBB base:', tbb_basedir
#print 'CWD: ', os.getcwd()

ccflags = []
cxxflags = [
    '-m64',
    '-march=native',
    '-I{0}'.format(tbb_basedir),
    '-I{0}'.format(os.path.join(tbb_basedir, 'src')),
    #'-I{0}'.format(os.path.join(tbb_basedir, 'src/tbb')),
    '-I{0}'.format(os.path.join(tbb_basedir, 'src/rml/include')),
    '-I{0}'.format(os.path.join(tbb_basedir, 'include')),
]
cppdefines = [
#    'DO_ITT_NOTIFY',
    'USE_PTHREAD',
    '__TBB_BUILD=1',
]
linkflags = []

if g_CONFIGURATION['build'] == 'debug':
    ccflags.extend([
        '-O0',
        '-g',
        '-ggdb2',
    ])
    cppdefines.extend([
        'TBB_USE_DEBUG',
    ])

else:
    ccflags.extend([
        '-O2',
    ])


tbbenv = Environment(
    platform = 'posix',
    CCFLAGS=ccflags,
    CXXFLAGS=cxxflags,
    CPPDEFINES=cppdefines,
    LINKFLAGS=linkflags
)

############################################################################
# Build verbosity
if not SCutils.has_option('verbose'):
    SCutils.setup_quiet_build(tbbenv, True if SCutils.has_option('colorblind') else False)
############################################################################



tbbmallocenv = tbbenv.Clone()

tbbmallocenv.Append(CCFLAGS=[
    '-fno-rtti',
    '-fno-exceptions',
    '-fno-schedule-insns2',
])

#tbbenv.Command('version_string.tmp', None, '')

# Write version_string.tmp
with open(os.path.join(os.getcwd(), 'version_string.tmp'), 'wb') as fd:
    (out, err, ret) = utils.xcall([
        '/bin/bash',
        os.path.join(g_CONFIGURATION['basedir'], '3rd-party/tbb40_233oss/build/version_info_linux.sh')
    ])

    if ret:
        raise SCons.Errors.StopError('version_info_linux.sh execution failed')

    fd.write(out);
    #print 'put version_string in', os.path.join(os.getcwd(), 'version_string.tmp')
    #print out
    fd.close()

result = []

def setup_tbb():
    print 'CWD: ', os.getcwd()
    tbb_sources = SCutils.find_files(os.path.join(tbb_basedir,'src/tbb'), r'^.*\.cpp$')
    tbb_sources.extend([
        'src/tbbmalloc/frontend.cpp',
        'src/tbbmalloc/backref.cpp',
        'src/tbbmalloc/tbbmalloc.cpp',
        'src/tbbmalloc/large_objects.cpp',
        'src/tbbmalloc/backend.cpp',
        'src/rml/client/rml_tbb.cpp',
    ])


    print tbb_sources
    result.append(tbbenv.StaticLibrary(target='libtbb', source=tbb_sources))


setup_tbb()

Return('result')
...