任务是衡量new
对自定义分配器的效果:Stack<size>
。我认为足够的方法是测量分配给定大小的多个内存块所花费的时间。选定的范围是:
bytes:100,1000,...,1000000
块数:20000,40000,...,200000
要衡量new
和Stack
,请使用以下代码:
#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
对吗?
由于某种原因我无法在 回答者@ user4581301在下面的评论中。 Test_Object
中为超过2500- 2600 Stack
分配内存,为什么?
有没有办法让迭代超过内存块的大小,这里变化#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
答案 0 :(得分:2)
使用C ++ 11中的std::chrono
,它非常准确。如果您的编译器不支持它,您可以在Windows上使用QueryPerformanceCounter
。