可能以有效的方式在模拟的循环中进行多线程

Possible to multi-thread inside the loop of simulation in an efficient manner?

本文关键字:循环 多线程 模拟 有效 方式      更新时间:2023-10-16

我的问题是关于如何以实际上不会降低模拟的性能而不是增加它的方式正确设计以下多线程。

假设您有一个称为MyClass的类,该类容纳了几个大数组(每个大约500MB(和一个通过使用此类数组来处理信息的函数:

class MyClass
{
private:
    int *data1 = new int[ARRAY_SIZE]();
    int *data2 = new int[ARRAY_SIZE]();
public:
    void fillData(); //any function that fills the inner data
    void processData(const int iteration);
}

仿真的每一次迭代,处理了4个MyClass的实例。在我理想的世界中,我想做的是将每种实例传递到一个线程,然后在每个线程中,致电instance.processData()。使用#include <thread>,看起来如下:

int main()
{
    MyClass inst1,inst2, inst3, inst4;
    //<----- here you would have code that fills the arrays inside each instance of MyClass
    for(int iteration=0; iteration<MAX_ITERATIONS; iteration++)
    {
        std::thread t1(&MyClass::processData, &inst1, iteration);
        std::thread t2(&MyClass::processData, &inst2, iteration);
        std::thread t3(&MyClass::processData, &inst3, iteration);
        std::thread t4(&MyClass::processData, &inst4, iteration);
        t1.join();
        t2.join();
        t3.join();
        t4.join();
    }
    return 0;
}

我将 MyClass实例派遣到线程的原因是,每个迭代的每个迭代是在每个实例结束的 processData结束之后,我都在每个实例中的数据结果之间进行比较,每个实例中的每个迭代。p>问题在于,所描述的代码实际上比非量化版本(例如慢的级数(要慢得多。然后问题变成:我在做什么错?考虑到我必须比较每个迭代结束时每个实例的处理结果吗?

是否有改进的方法?

ps1:我绝对无法将processData中包含的过程归根量。这是100%毫无疑问的。

ps2:虽然我无法透露与真实代码本身有关的任何内容,但如果它可以帮助我进行上面写的摘要并将它们作为一个真正的编译示例。尽管我认为没有它可能足够清楚。

有几件事可能会导致您使用四个线程而不是一个线程看到性能下降。这是要检查的基本内容:

  • 并行化开销:这是创建和同步线程的成本。如果processData中完成的工作量较低,并且您有大量迭代,那么线程创建和破坏成本可能是一个问题。如果您在processData()内有任何同步构建体,例如障碍物,锁或原子操作,则可能是放慢速度的来源。

  • thrashing:当单个线程执行时,活动内存集(正在写入并从中读取的存储器的集合(通常比多个线程运行时小得多。这可能会导致大量的缓存错过(即,由于多个线程必须共享L2和L3缓存(。如果您的程序超出了系统上的物理内存量(即交换(,则多个线程可能会导致页面触摸,而招标线程不会。

  • 资源争夺:如果您的过程是读/写入磁盘或网络,则您可能会经历类似于使用该资源的thrash的东西,在这种资源中,差异线程互相阻止彼此有效地访问它。

  • false共享:这是线程在同一缓存线上写和读取到不同位置的地方,反复导致计算被丢弃,因为缓存线被无效并刷新。

允许更好诊断的问题:

  1. 串行运行时,每次迭代的总壁时钟时间是多长时间?

  2. 使用四个线程时,每次迭代的总壁时钟时间是多长时间?

  3. 哪种类型的操作/算法是processData()(例如,排序,稀疏线性代数,密度线性

  4. 该系统的物理规范是什么(即,它具有多少个物理和逻辑核心,卡车有多大,有多少物理记忆(?

  5. 执行了多少次迭代?