1

我正在制作一个太空行星模拟器,问题是,我无法模拟超过 100 颗行星,因为模拟速度呈指数级下降。为了解决这个问题,我认为使用线程可以解决我的问题,因为我可能没有足够的经验使用显卡处理器进行计算。

我的程序中有两个函数用于计算行星之间的引力,另一个用于检查碰撞。我以某种方式实现了线程,所以我计算一个线程中的重力和另一个线程中的碰撞。

问题是模拟在不使用线程的情况下并没有运行得更快。也许我执行错误?

int main()
{
    int numOfPlanets;
    cout << "Enter the maximum number of planets to generate: ";
    cin >> numOfPlanets;
    App.Create(sf::VideoMode(1366, 740), "SFML Galaxy Simulator");
    App.Clear(sf::Color(20,20,20));

    generateRandomPlanets(500, 500, numOfPlanets);
    //createPlanet(planets, sf::Vector2f(500,500), sf::Vector2f(0,0), 5, 500);

    thread thread_1;
    thread thread_2;


    while(App.IsOpened())
    {
        sf::Event Event;
        while (App.GetEvent(Event))
        {
            if (Event.Type == sf::Event::Closed)
                App.Close();
        }

        App.Clear(sf::Color(20,20,20));
        thread_1 = thread(checkCollision);
        thread_2 = thread(calculateForce);
        thread_1.join();
        thread_2.join();
        updatePlanets();
        App.Display();
    }
    thread_2.join();
    thread_1.join();
    return 0;
}
4

2 回答 2

2
    thread_1 = thread(checkCollision);
    thread_2 = thread(calculateForce);
    thread_1.join();
    thread_2.join();
    updatePlanets();

这会启动两个新线程以并行执行一些工作,然后阻塞等待它们完成,然后再运行updatePlanets。你可能想要:

    thread_1 = thread(checkCollision);
    thread_2 = thread(calculateForce);
    updatePlanets();
    thread_1.join();
    thread_2.join();

这将并行运行三个函数。

此外,这是结尾处的错误main

thread_2.join();
thread_1.join();
return 0;

您已经加入了线程,您不能再次加入它们。

实际上没有必要在循环之外声明thread_1thread_2重用它们,你可以在循环中声明它们:

    thread thread_1(checkCollision);
    thread thread_2(calculateForce);
    updatePlanets();
    thread_1.join();
    thread_2.join();

另请注意,如果updatePlanets抛出异常,它将终止您的程序,因为thread_2析构函数将在线程可连接时运行,因此 call terminate(),这在该程序中可能没问题,但需要牢记。

于 2013-03-06T20:35:44.207 回答
1

在发布问题后,我进行了更多研究,发现模拟性能的主要问题是计算每个行星相对于所有其他行星的引力的算法的时间复杂度O(n^2)

我发现,解决这个问题的一种或最好的方法是使用Barnes-Hut算法进行 n 体模拟,其时间复杂度为O(n log n). 该算法的工作方式是将所有行星划分为四叉树节点,然后根据每个节点的中心质量计算力。

因此,将所有这些加在一起,使用 Barnes-Hut 算法和线程是解决这个问题的最佳方法。

于 2013-03-07T14:15:13.203 回答