我有一个数据集,我想以tbb::parallel_forsize 的间隔使用它interval_size。我的函子消耗的每个间隔应该是interval_size,除了最后一个部分间隔,当interval_size不均匀划分我的数据集时,它可能会更小。
有没有办法使用TBB以这种方式进行静态分区?该测试产生的间隔比interval_size我的系统上的要小:
#include <tbb/parallel_for.h>
#include <iostream>
struct body
{
void operator()(const tbb::blocked_range<size_t> &r) const
{
std::cout << "range size: " << r.end() - r.begin() << std::endl;
}
};
int main()
{
size_t num_intervals = 4;
size_t interval_size = 3;
// consume num_intervals plus a partial interval in total
size_t n = num_intervals * interval_size + (interval_size - 1);
tbb::parallel_for(tbb::blocked_range<size_t>(0, n, interval_size),
body(),
tbb::simple_partitioner());
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
$ g++ …Run Code Online (Sandbox Code Playgroud) 我看到它tbb::concurrent_unordered_map非常接近,std::unordered_map同时对于并发来说是安全的。我也知道这unsafe_erase不是并发安全的insert等等。迭代器文档还指出任何现有的迭代器仍然有效insert,find等等。
问题是,除了要求擦除的迭代器之外,是否unsafe_erase会使任何其他迭代器失效?
std::unordered_map并且std::map肯定有这种行为,但它没有在concurrent_unordered_map任何地方的文档中指定。
我有一个const函数对象,并且对于时间,它返回无效.但可以返回int或double.我正在用c ++ 11样式编写代码,并且只是尝试使用auto作为返回类型.虽然代码编译,但我不确定它是否100%正确.这是代码.
template <typename graph_t>
struct my_func {
public:
my_func() { }
my_func (graph_t& _G) : G(_G) { }
template <typename edge_t>
auto operator()(edge_t edge) -> void const {
//do something with the edge.
} //operator
private:
graph_t& G;
};
//call the functor: (pass graph G as template parameter)
std::for_each(beginEdge, endEdge, my_func<Graph>(G));
Run Code Online (Sandbox Code Playgroud)
此代码完美地编译并在串行模式下工作.现在我尝试使用intel TBB parallel_for_each()并行化上面的for_each.这要求函数对象为const.意味着不应该允许线程修改或更改函数对象的私有变量.
//tbb::parallel_for_each
tbb::paralle_for_each(beginEdge, endEdge, my_func<Graph>(G));
Now, the compiler error comes:
passing const my_func< ... > .. discards qualifiers
Run Code Online (Sandbox Code Playgroud)
所以我不得不将operator()()更改为以下内容:
template <typename edge_t>
void operator()(edge_t edge) …Run Code Online (Sandbox Code Playgroud) 编辑:< Matlab限制TBB但不限制OpenMP >我的问题与上面的问题不同,虽然使用相同的示例代码进行说明,但它并没有重复.在我的情况下,我在tbb初始化中指定了多个线程,而不是使用"deferred".另外我在谈论cx中TBB与TBM中TBB之间的奇怪行为.该问题的答案仅演示了在C++中运行TBB时的线程初始化,而不是在MEX中.
我正在尝试提升Matlab mex文件以提高性能.在mex中使用TBB时遇到的奇怪之处是TBB初始化不能按预期工作.
这个C++程序执行100%的cpu使用,并且在单独执行时有15个TBB线程:
main.cpp中
#include "tbb/parallel_for_each.h"
#include "tbb/task_scheduler_init.h"
#include <iostream>
#include <vector>
#include "mex.h"
struct mytask {
mytask(size_t n)
:_n(n)
{}
void operator()() {
for (long i=0;i<10000000000L;++i) {} // Deliberately run slow
std::cerr << "[" << _n << "]";
}
size_t _n;
};
template <typename T> struct invoker {
void operator()(T& it) const {it();}
};
void mexFunction(/* int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[] */) {
tbb::task_scheduler_init init(15); // 15 threads …Run Code Online (Sandbox Code Playgroud) 我读了这些主题:
使用 gcc 在 Linux 上运行线程构建模块 (Intel TBB)
无法将英特尔 TBB 库与 /usr/lib 中的 libtbb 链接
但仍然收到此错误:
piCalc.cpp:8:17: fatal error: ttb.h: No such file or directory
#include "ttb.h"
Run Code Online (Sandbox Code Playgroud)
我计算 pi 的代码始于
#include <iostream>
#include "ttb.h"
#include "parallel_for.h"
Run Code Online (Sandbox Code Playgroud)
运行安装了 nvidia 和 cuda 的 Ubuntu 14.04。为了安装 TBB,我从以下开始:
sudo apt-get install libtbb-dev
Run Code Online (Sandbox Code Playgroud)
它说
Reading package lists... Done
Building dependency tree
Reading state information... Done
libtbb-dev is already the newest version.
The following package was automatically installed and is no …Run Code Online (Sandbox Code Playgroud) 我正在使用 CMake 构建跨平台项目。目前我正在尝试在 Linux 上运行它。我最近添加了一个用于运行测试的项目,但它无法运行,因为它找不到共享库之一,特别是libtbbmalloc.so.2:
/tests: error while loading shared libraries: libtbbmalloc.so.2: cannot open shared object file: No such file or directory`
Run Code Online (Sandbox Code Playgroud)
当我ldd在可执行文件上运行时,我得到以下信息:
linux-vdso.so.1 (0x00007fffeb572000)
libtbbmalloc_proxy.so.2 => /home/username/dev/tbb/libtbbmalloc_proxy.so.2 (0x00007f50afe00000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f50afa70000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f50af6d0000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f50af4b0000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f50af0a0000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f50aee90000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f50aec70000)
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f50aea60000)
/lib64/ld-linux-x86-64.so.2 (0x00007f50b0400000)
libtbbmalloc.so.2 => not found
Run Code Online (Sandbox Code Playgroud)
我的测试项目的 CMakeLists.txt 如下所示:
set(test_sourcefiles main_tests.cpp)
add_executable(tests ${test_sourcefiles})
target_link_libraries(tests Catch2::Catch2 MyLib)
Run Code Online (Sandbox Code Playgroud)
MyLib 使用 tbb,我想这就是我的可执行文件( …
我有一个非常简单的 parallel_for 循环
tbb::parallel_for(tbb::blocked_range<int>(0, values.size()),
[&](tbb::blocked_range<int> r)
{
for (int i = r.begin(); i < r.end(); ++i)
{
values[i] = std::sin(i * 0.001);
}
});
Run Code Online (Sandbox Code Playgroud)
其中“值”是双精度向量。我想知道的是哪些线程在循环中的哪个范围内工作。是否可以从 TBB 获取某种线程 ID?
注意:这不是这个问题的重复。
给定一个与 TBB 并行的复杂软件,我如何完全关闭线程?我知道task_scheduler_init:
int nthreads = tbb::task_scheduler_init::default_num_threads();
const char* cnthreads = getenv("TBB_NUM_THREADS");
if (cnthreads) nthreads = std::max(1, atoi(cnthreads));
tbb::task_arena arena(nthreads, 1);
tbb::task_scheduler_init init(nthreads);
Run Code Online (Sandbox Code Playgroud)
但是,此解决方案(与此相关)不会关闭线程。TBB 仍然会创建大量线程,nthreads只是使其中一些线程未被使用。此外,如果有nthreads = 1,TBB 实际上会创建 1 个额外的线程 - 加上主线程总共 2 个线程。
是的,在某些情况下,您确实希望完全关闭线程,但仍保持 TBB 代码处于活动状态。我当前的解决方案是对 tbb 进行草率的包装:
namespace hddm {
bool enableTBB = true;
class task_group {
unique_ptr<tbb::task_group> tbb;
public :
task_group() {
if (enableTBB)
tbb.reset(new tbb::task_group());
}
template<typename F>
void run(const F& f) { …Run Code Online (Sandbox Code Playgroud) 当我在代码中使用 oneDPL 时,我面临以下问题:
/usr/lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/pstl/parallel_backend_tbb.h:70:10: error: no member named 'task' in namespace 'tbb'
Run Code Online (Sandbox Code Playgroud)
为什么会发生这种情况以及如何解决它?
我已经tbb下载并放置在我的存储库目录中:
> tree deps/tbb/ -d \ndeps/tbb/\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 bin\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 cmake\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 templates\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 include\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 serial\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 tbb\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 tbb\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 compat\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 internal\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 machine\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 lib\n \xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 ia32\n \xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 gcc4.8\n \xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 intel64\n \xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 gcc4.8\nRun Code Online (Sandbox Code Playgroud)\n在我的CMakeLists.txt我已经尝试过这个:
include_directories("deps/tbb/include")\n\n\nfind_library(TBB_LIB\n NAMES\n tbbbind_debug\n tbbbind\n tbb_debug\n tbbmalloc_debug\n tbbmalloc_proxy_debug\n tbbmalloc_proxy\n tbbmalloc\n tbb_preview_debug\n tbb_preview\n tbb\n HINTS "${CMAKE_PREFIX_PATH}/deps/tbb/lib/intel64/gcc4.8"\n)\n\nadd_executable(${PROJECT_NAME}\nsrc/main.cpp\n)\n\ntarget_link_libraries(${PROJECT_NAME} PUBLIC ${TBB_LIB})\nRun Code Online (Sandbox Code Playgroud)\n但是使用cmake, 链接器构建会引发此错误:
\n\n/usr/lib64/gcc/x86_64-suse-linux/7/../../../../x86_64-suse-linux/bin/ld:找不到-lTBB_LIB-NOTFOUND
\ncollect2:错误:ld 返回 1 退出状态
\n
我无法弄清楚缺少什么。谢谢。
\n