簡體   English   中英

如何加快在C ++中返回指向對象的指針的函數?

[英]How to speed up a function that returns a pointer to object in c++?

我是機械工程師,所以請理解我沒有接受正確的編碼培訓。 我有一個有限元代碼,它使用網格來制作構成模型的元素。 該元素對這個問題並不重要,因此我省略了。 元素和網格從文件中讀取,並且該部分正常工作。

class Grid
{
private:
    int id;
    double x;
    double y;
    double z;
public:
    Grid();
    Grid(int, double, double, double);
    int get_id() { return id;};
};

Grid::Grid() {};
Grid::Grid(int t_id, double t_x, double t_y double t_z)
{
    id = t_id; x = t_x; y = t_y; z = t_z;
}

class SurfaceModel
{
private:
    Grid** grids;
    Element** elements;
    int grid_count;
    int elem_count;
public:
    SurfaceModel();
    SurfaceModel(int, int);
    ~SurfaceModel();
    void read_grid(std::string);
    int get_grid_count() { return grid_count; };
    Grid* get_grid(int);
};

SurfaceModel::SurfaceModel()
{
    grids = NULL;
    elements = NULL;
}

SurfaceModel::SurfaceModel(int g, int e)
{
    grids = new Grid*[g];
    for (int i = 0; i < g; i++)
        grids[i] = NULL;
    elements = new Element*[e];
    for (int i = 0; i < e; i++)
        elements[i] = NULL;
}

void SurfaceModel::read_grid(std::string line)
{
    ... blah blah ...
    grids[index] = new Grid(n_id, n_x, n_y, n_z);
    ... blah blah ....
}

Grid* SurfaceModel::get_grid(int i)
{
    if (i < grid_count)
        return grids[i];
    else
        return NULL;
}

當我需要實際使用網格時,我使用get_grid可能是這樣的:

SurfaceModel model(...);
.... blah blah ..... 
for (int i = 0; i < model.get_grid_count(); i++)
{
    Grid *cur_grid = model.get_grid(i);
    int cur_id = cur_grid->get_id();
}

我的問題是,對get_grid的調用似乎比我認為簡單地返回我的對象​​要花費更多的時間。 我在代碼上運行了gprof,發現在進行非常大的模擬時,get_grid被調用了約40億次,並且使用x,y,z進行的另一操作大致相同。 該運算會進行一些乘法。 我發現get_grid和數學運算大約花費相同的時間(約40秒)。 看來我做錯了什么。 有沒有更快的方法讓那個物體離開那里?

我認為您忘記設置grid_countelem_count

這意味着它們將具有未初始化的( 不確定的 )值。 如果循環使用這些值,則可以輕松地循環大量迭代。

SurfaceModel::SurfaceModel() 
   : grid_count(0), 
     grids(NULL),
     elem_count(0),
     elements(NULL)
{
}

SurfaceModel::SurfaceModel(int g, int e)
   : grid_count(g), 
     elem_count(e)
{
    grids = new Grid*[g];
    for (int i = 0; i < g; i++)
        grids[i] = NULL;
    elements = new Element*[e];
    for (int i = 0; i < e; i++)
        elements[i] = NULL;
}

然而,我建議您要擺脫該程序中new的每個實例(並為網格使用向量)

在現代CPU上訪問內存通常比進行乘法需要更長的時間。 在現代系統上獲得良好性能往往意味着更多地關注優化內存訪問而不是優化計算。 因為您將網格對象存儲為動態分配的指針數組,所以網格對象本身將不連續存儲在內存中,並且在嘗試訪問它們時可能會遇到許多緩存未命中的情況。 在此示例中,通過將網格對象直接存儲在數組或向量中,您可能會看到明顯的加速,因為您將訪問循環中的連續內存,因此可以獲得良好的緩存利用率和有效的硬件預取。

一微秒40億次(在許多情況下這是一個相當可接受的時間)可以提供4 000秒。 而且由於您只能得到大約40秒(如果我做對了),因此我懷疑這里是否存在嚴重錯誤。 如果任務仍然很慢,我會考慮使用並行計算。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM