测量(自定义)分配器的执行时间?

时间:2017-05-29 14:01:58

标签: c++ memory-management time

任务是衡量new对自定义分配器的效果:Stack<size>。我认为足够的方法是测量分配给定大小的多个内存块所花费的时间。选定的范围是:

  • bytes:100,1000,...,1000000

  • 块数:20000,40000,...,200000

要衡量newStack,请使用以下代码:

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <cstddef>                  // std::size_t
#include <ctime>                    // std::clock_t

#include "MyStack.h"

#define BLOCK_SIZE 100              // Test_Object size    

struct Measurement
{
   Measurement(std::size_t n, double t): blocks_number(n), cpu_time(t) { }

   std::size_t blocks_number;
   double cpu_time;
};

//----------------------------------------------------------------------------
class Test_Object
{
    char data[BLOCK_SIZE];
};

//----------------------------------------------------------------------------
void sequential_deallocation(std::size_t number)
{
    std::vector<Test_Object*> obj_arr(number + 1);

    // allocate
    for (std::size_t allocations = 0; allocations <= number; ++allocations)
    {
        obj_arr[allocations] = new Test_Object;
    }

    // deallocate in reverse order
    for (std::size_t allocations = number; allocations-- > 0;)
    {
        delete obj_arr[allocations];
    }
}

//----------------------------------------------------------------------------
void time_test()
{
    std::vector<Measurement> data; 

    for (std::size_t number = 20000; number <= 200000; number += 20000) // memory block number 
    {
        std::clock_t start = std::clock();

        sequential_deallocation(number);

        // find CPU execution time
        double time = 1000.0 * (std::clock() - start) / CLOCKS_PER_SEC;

        data.emplace_back(Measurement(number, time));
    }

    std::string name("OperatorNewSize");     
    name += std::to_string(BLOCK_SIZE) + ".txt";
    write_to_file(name, data); // writes the contents of vector: data to file: name
}

//----------------------------------------------------------------------------

int main ()
try
{
    // measure new
    time_test(); 

    // measure Stack
    const std::size_t number = 2500;
    const std::size_t bytes = number * sizeof(Test_Object);
    Stack<bytes> s;

    std::vector<Test_Object*> obj_vect(number);

    std::clock_t start = std::clock();
    for (std::size_t allocations = 0; allocations < number; ++allocations)
    {
        obj_vect[allocations] = reinterpret_cast<Test_Object*>(s.get(sizeof(Test_Object)));
    }


    for (std::size_t allocations = number; allocations-- > 0;)
    {
        s.free(); // not sure if right
    }

    double time = 1000.0 * (std::clock() - start) / CLOCKS_PER_SEC;
    std::cout <<"Block Size: "<< BLOCK_SIZE <<"\tBlock Number: "<< number <<"\tTime: "<< time <<" [ms]\n";
}
catch (std::exception& e)
{
    std::cerr << e.what();
    getchar();
}

我不知道我使用的方法是否正确,即编译器是否优化了使时间测量无效的代码的某些部分。我将指定内存的指针存储在向量中,我不知道这是不对的

我主要担心的是:

  • 描述的方法有效吗?

  • 如何存储保存已分配内存的指针:vector,array?

  • 衡量Stack对吗?

  • 由于某种原因我无法在Test_Object中为超过2500- 2600 Stack分配内存,为什么? 回答者@ user4581301在下面的评论中。

  • 有没有办法让迭代超过内存块的大小,这里变化#define BLOCK_SIZE 100;或模板参数指定Stack<size>

  • 的大小

MyStack.h

#ifndef MyStack_h
#define MyStack_h

template <std::size_t N>                                     
class Stack
{
    typedef unsigned char uchar;
    typedef std::size_t uint;

    uchar* data;                                                
    uchar* end;                                              
    uchar* top;                                              

    uint index;
    uint memory_blocks_sizes[N];            // byte is the smallest memory unit 

    bool is_full() { return !(top < end); }

    bool is_empty() { return top == data && index == 0; }

    void update(uint n, bool allocate) 
    {
        if (allocate)
        {
           top += n;                        // shift top n bytes towards the end        
            memory_blocks_sizes[index] = n; // store size of allocated block
            ++index;                        // update index to store next
        }
        else
        {
            --index;                        // update index to get previous
            n = memory_blocks_sizes[index]; // get size of last allocated block
            top -= n;                       // shift top towards the start(data)
        }
    }

public:
    Stack()
        : data(new uchar[N]), end(data + N), top(data), index(0)
    {

    }

    ~Stack() { delete[] data; }

    void* get(uint n)
    {
        if (is_full() || ((top + n) > end))
        {
            throw std::bad_alloc("Stack::get()::Stack Overflow!\n");
        }
        void* ret = (void*) top;

        update(n, true);

        return ret;
    }

    void free()
    {
        if (is_empty())
        {
            throw std::bad_alloc("Stack::free()::Stack Underflow!\n");
        }
        update(0, false);
    }

    uint available() const { return uint(end - top); };
};


#endif

1 个答案:

答案 0 :(得分:2)

使用C ++ 11中的std::chrono,它非常准确。如果您的编译器不支持它,您可以在Windows上使用QueryPerformanceCounter