2013-03-06 43 views
1

我正在模拟太空中的行星,问题是,我无法模拟超过100颗行星,因为模拟速度呈指数级下降。为了解决这个问题,我认为使用线程可以解决我的问题,因为我可能没有经历过使用图形卡处理器来计算。在行星模拟器中使用boost :: thread

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

问题是,如果没有使用线程,模拟运行速度不会更快。也许我正在实施他们错了?

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; 
} 
+2

不要认为*只是带线程*可以提高性能...在数据结构和算法方面考虑。您可能需要进行结构更改才能准备并行执行的应用程序。 – 2013-03-06 20:34:22

回答

1
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析构函数将在线程可连接时运行,因此请致电terminate(),这在此程序中可能没有问题,但需要牢记。

+0

即使按照你的说法,在表现上仍然没有差异 – user2141481 2013-03-06 20:49:32

1

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

我发现,或者最好的方法是通过使用Barnes-Hut算法进行n体仿真,其时间复杂度为O(n log n)。该算法的工作原理是将所有行星划分为四叉树节点,然后根据每个节点的中心质量计算力。

所以为了将所有这些加在一起,使用Barnes-Hut算法和线程一起处理这个问题是最好的方法。