3

データ指向の設計実験を始めました。私は最初にいくつかの oop コードを実行し始めましたが、一部のコードが非常に遅いことがわかりました。理由はわかりません。ここに一例があります: 私はゲームオブジェクトを持っています

    class GameObject
    {
    public:
          float m_Pos[2];
          float m_Vel[2];
          float m_Foo;

          void UpdateFoo(float f){
             float mag = sqrtf(m_Vel[0] * m_Vel[0] + m_Vel[1] * m_Vel[1]);
             m_Foo += mag * f;
          }
     };

次に、new を使用して 1,000,000 個のオブジェクトを作成し、UpdateFoo() の呼び出しをループします。

        for (unsigned i=0; i<OBJECT_NUM; ++i)
        {
           v_objects[i]->UpdateFoo(10.0);
        }

ループを終了するには約 20ms かかります。そして、float m_Pos[2] をコメントアウトすると奇妙なことが起こったので、オブジェクトは次のようになります

    class GameObject
    {
    public:
          //float m_Pos[2];
          float m_Vel[2];
          float m_Foo;

          void UpdateFoo(float f){
             float mag = sqrtf(m_Vel[0] * m_Vel[0] + m_Vel[1] * m_Vel[1]);
             m_Foo += mag * f;
          }
     };

そして突然、ループが完了するまでに約150msかかります。そして、m_Vel の前に何かを置くと、はるかに速くなります。m_Vel と m_Foo の間、または m_Vel....slow の前の場所を除く他の場所にパディングを入れようとします。

リリース ビルド i7-4790 で vs2008 と vs2010 をテストしました。キャッシュの一貫した動作に関連していますか。

ここにサンプル全体があります:

    #include <iostream>
    #include <math.h>
    #include <vector>
    #include <Windows.h>

    using namespace std;

    class GameObject
    {
    public:
        //float m_Pos[2];
        float m_Velocity[2];
        float m_Foo;

        void UpdateFoo(float f)
        {
          float mag = sqrtf(m_Velocity[0] * m_Velocity[0] + m_Velocity[1] * 
                            m_Velocity[1]);
          m_Foo += mag * f;
         }
    };



     #define OBJECT_NUM 1000000

     int main(int argc, char **argv)
     {
       vector<GameObject*> v_objects;
       for (unsigned i=0; i<OBJECT_NUM; ++i)
       {
          GameObject * pObject = new GameObject;
          v_objects.push_back(pObject);
       }

       LARGE_INTEGER nFreq;
       LARGE_INTEGER nBeginTime;
       LARGE_INTEGER nEndTime;
       QueryPerformanceFrequency(&nFreq);
       QueryPerformanceCounter(&nBeginTime);

       for (unsigned i=0; i<OBJECT_NUM; ++i)
       {
           v_objects[i]->UpdateFoo(10.0);
       }

       QueryPerformanceCounter(&nEndTime);
       double dWasteTime = (double)(nEndTime.QuadPart-
                       nBeginTime.QuadPart)/(double)nFreq.QuadPart*1000;

       printf("finished: %f", dWasteTime);

       //   for (unsigned i=0; i<OBJECT_NUM; ++i)
       //   {
       //       delete(v_objects[i]);
       //   }
     }
4

1 に答える 1