我完全是多核编程的新手,但我知道如何编写C++.
现在,我正在寻找多核编程库.我只想尝试一下,只是为了好玩,现在,我找到了3个API,但我不确定应该坚持哪一个.现在,我看到了Boost的MPI,OpenMP和TBB.
对于任何经历过这3个API(或任何其他API)中的任何一个的人,您能否告诉我这些之间的区别?是否有任何因素需要考虑,如AMD或英特尔架构?
我有一个数据集,我想以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) 好的,代码是:
vector<vector<double>> imageFiltered;
// some processing codes here
parallel_for( blocked_range<unsigned>(0, imageFiltered.size()),
[=](const blocked_range<unsigned>& r) {
for( unsigned i = r.begin(); i != r.end(); ++i ){
for( unsigned j = 0; j != imageFiltered[i].size(); ++j ) {
imageFiltered[i][j] = 0; // error here?expression must be a modifiable lvalue
}
}
});
Run Code Online (Sandbox Code Playgroud)
我写了另一个类似的代码块,它工作得很好。所以,这里有一点帮助。PS:parallel_for 来自 Interl TBB。
测试程序:
#include <tbb/parallel_invoke.h>
int main(void)
{
tbb::parallel_invoke([]{},[]{});
return 0;
}
Run Code Online (Sandbox Code Playgroud)
g++ -std=c++11 tmp.cpp -ltbb检查过
valgrind --tool=memcheck --track-origins=yes \
--leak-check=full --log-file=report ./a.out`
Run Code Online (Sandbox Code Playgroud)libtbb版本:4.0,valgrind版本:3.8.1。
以上部分测试结果:
possibly lost: 1,980 bytes in 6 blocks
Run Code Online (Sandbox Code Playgroud)
问题是:
这是一个TBB错误吗?
或者这possible lost实际上是安全的,这只是 valgrind 认为不安全的一些代码?
在此std :: function vs template链接中,对std :: function的开销进行了很好的讨论。基本上,为避免传递给std :: function构造函数的函子的堆分配导致10倍的开销,必须使用std :: ref或std :: cref。
来自@CassioNeri答案的示例显示了如何通过引用将lambdas传递给std :: function。
float foo(std::function<float(float)> f) { return -1.0f * f(3.3f) + 666.0f; }
foo(std::cref([a,b,c](float arg){ return arg * 0.5f; }));
Run Code Online (Sandbox Code Playgroud)
现在,英特尔线程构建模块库使您能够使用lambda / functor并行评估循环,如下例所示。
示例代码:
#include "tbb/task_scheduler_init.h"
#include "tbb/blocked_range.h"
#include "tbb/parallel_for.h"
#include "tbb/tbb_thread.h"
#include <vector>
int main() {
tbb::task_scheduler_init init(tbb::tbb_thread::hardware_concurrency());
std::vector<double> a(1000);
std::vector<double> c(1000);
std::vector<double> b(1000);
std::fill(b.begin(), b.end(), 1);
std::fill(c.begin(), c.end(), 1);
auto f = [&](const tbb::blocked_range<size_t>& r) {
for(size_t j=r.begin(); j!=r.end(); ++j) …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任何地方的文档中指定。
我想在一组块上并行执行for循环(使用TBB),其中每个块将使用用户提供的函数进行处理.通常情况下,我会这样做tbb::parallel_for().由于各种原因,我希望能够将处理块的线程数限制为规定的数量,然后调用它j.通常情况下,我会这样做tbb::task_scheduler_init(j).
但是,我希望用户可以选择使用TBB,具体来说,让用户提供的功能使用但仍有许多内核.所以我认为tbb::task_scheduler_init()是出局.我能看到的唯一解决方案是让用户调用tbb::task_scheduler_init()(或一起忽略它),并在正常的for循环中自行旋转我自己的j实例tbb::tbb_thread.我错过了什么吗?在TBB中有更自然的方法吗?是否有某种分层版本tbb::task_scheduler_init()?
我读了这些主题:
使用 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?