c++ - 使用 TBB 的一个简单示例

标签 c++ tbb

我是 TBB 的新手,尝试做一个简单的实验。

我的函数数据是:

int n = 9000000;
int *data = new int[n];

我创建了一个函数,第一个不使用 TBB 的函数:

void _array(int* &data, int n) {
        for (int i = 0; i < n; i++) {
            data[i] = busyfunc(data[i])*123;
        }
}

耗时 0.456635 秒。

并且还创建了一个 to 函数,第一个使用 TBB 的函数:

void parallel_change_array(int* &data,int list_count) {
    //Instructional example - parallel version
    parallel_for(blocked_range<int>(0, list_count),
        [=](const blocked_range<int>& r) {
        for (int i = r.begin(); i < r.end(); i++) {
            data[i] = busyfunc(data[i])*123;
        }
    });
}

我花了 0.584889 秒。

至于busyfunc(int m):

int busyfunc(int m)
{
    m *= 32;
    return m;
}

你能告诉我,为什么不使用 TBB 的函数比使用 TBB 花费的时间少吗?

我认为,问题是函数简单,不用TBB也很容易计算。

最佳答案

首先,busyfunc() 似乎并不那么繁忙,因为 9M 元素的计算仅需半秒,这使得该示例相当受内存限制(未缓存的内存操作比算术操作占用的周期多几个数量级操作)。内存限制计算的规模不如计算限制好,例如普通内存复制通常可以扩展到不超过 4 倍,甚至可以在更多数量的内核/处理器上运行。

此外,内存绑定(bind)程序对 NUMA 效应更敏感,并且由于您使用标准 C++ 将此数组分配为连续内存,因此默认情况下它将完全分配在发生初始化的同一内存节点上。可以通过运行 numactl -i all -- 来更改此默认值。

最后但也是最重要的一点是,TBB 懒惰地初始化线程,而且非常缓慢。我猜你不打算编写一个在并行计算上花费 0.5 秒后退出的应用程序。因此,一个公平的基准应该考虑到实际应用中预期的所有预热效应。至少,它必须等到所有线程都启动并运行后才能开始测量。 This answer提出了一种方法。

[更新] 另请参阅 Alexey 的回答,了解编译器优化差异中潜伏的另一个可能原因。

关于c++ - 使用 TBB 的一个简单示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48915345/

相关文章:

c++ - createProcess() 不工作?

c++ - 在 C++ 类中调用 ODE 求解器 (odeint)

c++ - Intel TBB 禁用嵌套并行

c++ - 了解 tbb::parallel_reduce 的并发性

c++ - 共享内存中的 tbb concurent_hash_map

c++ - 遍历 RapidJson 中的数组并获取对象元素

c++ - avcodec_receive_packet 中的错误(gdi screenshot + ffmpeg)

c++ - 检测图像中的 U 形边缘

c++ - 如何使用 TBB 在单线程中运行一个函数

OpenCV 使用 TBB 为 ARM 配置(Ubuntu,3.0.63)