简体   繁体   中英

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

I am a mechanical engineer so please understand I am not trained in proper coding. I have a finite element code that uses grids to make elements which make a model. The element is not important to this question so I have left it out. The elements and grids are read in from a file and that part works.

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

When I need to actually use the grid I use the get_grid maybe something like this:

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();
}

My problem is that the call to get_grid seems to be taking more time than I think it should to simply return my object. I have run the gprof on the code and found that get_grid gets called about 4 billion times when going through a very large simulation and another operation using the x, y, z occurs about the same. The operation does some multiplication. What I found is that the get_grid and math take about the same amount of time (~40 seconds). This seems like I have done something wrong. Is there a faster way to get that object out of there?

I think you're forgetting to set grid_count and elem_count .

This means, they will have uninitialized ( indeterminate ) values. If you loop for those values, you can easily end up looping a lot of iterations.

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

Howeverm, I suggest you would want to get rid of each instance of new in this program (and use a vector for the grid)

On a modern CPU accessing memory often takes longer than doing multiplication. Getting good performance on modern systems can often mean focusing more on optimizing memory accesses than optimizing computation. Because you are storing your grid objects as an array of dynamically allocated pointers the grid objects themselves will be stored non-contiguously in memory and you will likely get many cache misses when trying to access them. In this example you would probably see a significant speedup by storing your grid objects directly in an array or vector since you will be accessing contiguous memory in your loop and so get good cache utilization and effective hardware prefetching.

4 billion times a microsecond (which is a pretty acceptable time in many cases) gives 4 000 seconds. And since you only get about 40 s (if I get it right), I doubt there's something seriously wrong here. If it's still slow for the task, I'd consider the use of parallel computing.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM