#include "stdafx.h"
#include <algorithm>
#include <cassert>
#include <iostream>
#include <map>
#include <memory>
#include <stack>
#include <vector>
#include <string>
#include <chrono>
#include <set>
#include <random>
using namespace std;
#define __AVX__
#ifdef __AVX__
#include <immintrin.h>
#else
#warning No AVX support - will not compile
#endif
//from granite
void* memalign_alloc(size_t boundary, size_t size)
{
#if defined(_WIN32)
return _aligned_malloc(size, boundary);
#elif defined(_ISOC11_SOURCE)
return aligned_alloc(boundary, size);
#elif (_POSIX_C_SOURCE >= 200112L) || (_XOPEN_SOURCE >= 600)
void *ptr = nullptr;
if (posix_memalign(&ptr, boundary, size) < 0)
return nullptr;
return ptr;
#else
// Align stuff ourselves. Kinda ugly, but will work anywhere.
void **place;
uintptr_t addr = 0;
void *ptr = malloc(boundary + size + sizeof(uintptr_t));
if (ptr == nullptr)
return nullptr;
addr = ((uintptr_t)ptr + sizeof(uintptr_t) + boundary) & ~(boundary - 1);
place = (void **)addr;
place[-1] = ptr;
return (void *)addr;
#endif
}
void* memalign_calloc(size_t boundary, size_t size)
{
void* ret = memalign_alloc(boundary, size);
if (ret)
memset(ret, 0, size);
return ret;
}
void memalign_free(void* ptr)
{
#if defined(_WIN32)
_aligned_free(ptr);
#elif !defined(_ISOC11_SOURCE) && !((_POSIX_C_SOURCE >= 200112L) || (_XOPEN_SOURCE >= 600))
if (ptr != nullptr)
{
void **p = (void **)ptr;
free(p[-1]);
}
#else
free(ptr);
#endif
}
template <typename T>
class ObjectPool
{
public:
template <typename... P>
T* allocate(P&&... p)
{
#ifndef OBJECT_POOL_DEBUG
if (vacants.empty())
{
unsigned num_objects = 64u << memory.size();
T* ptr = static_cast<T*>(memalign_alloc(std::max(size_t(64), alignof(T)),
num_objects * sizeof(T)));
if (!ptr)
return nullptr;
for (unsigned i = 0; i < num_objects; i++)
vacants.push_back(&ptr[i]);
memory.emplace_back(ptr);
}
T* ptr = vacants.back();
vacants.pop_back();
new(ptr) T(std::forward<P>(p)...);
return ptr;
#else
return new T(std::forward<P>(p)...);
#endif
}
void free(T* ptr)
{
#ifndef OBJECT_POOL_DEBUG
ptr->~T();
vacants.push_back(ptr);
#else
delete ptr;
#endif
}
void clear()
{
#ifndef OBJECT_POOL_DEBUG
vacants.clear();
memory.clear();
#endif
}
protected:
#ifndef OBJECT_POOL_DEBUG
std::vector<T*> vacants;
struct MallocDeleter
{
void operator()(T* ptr)
{
memalign_free(ptr);
}
};
std::vector<std::unique_ptr<T, MallocDeleter>> memory;
#endif
};
struct A
{
int aa[10];
};
struct B
{
int aa[1];
};
struct C
{
char aa[11];
};
struct D
{
char aa[110];
};
struct E
{
char aa[9];
};
unsigned long long SIZE = 0;
#if 0
int x = 0;
void tt()
{
int rd = x % 5;
x++;
switch (rd)
{
case 0:
{
new A;
SIZE += sizeof(A);
break;
}
case 1:
{
new B;
SIZE += sizeof(B);
break;
}
case 2:
{
new C;
SIZE += sizeof(C);
break;
}
case 3:
{
new D;
SIZE += sizeof(D);
break;
}
case 4:
{
new E;
SIZE += sizeof(E);
break;
}
}
}
int main(int argc, char** argv)
{
auto t = clock();
for (int i = 0; i < 1000 * 10000; i++)
tt();
cout << "time: " << (clock() - t) << endl;
cout << SIZE / (1024 * 1024) << endl;
getchar();
return 0;
}
#else
ObjectPool<A> pools_a;
ObjectPool<B> pools_b;
ObjectPool<C> pools_c;
ObjectPool<D> pools_d;
ObjectPool<E> pools_e;
int x = 0;
void tt()
{
int rd = x % 5;
x++;
switch (rd)
{
case 0:
{
pools_a.allocate();
SIZE += sizeof(A);
break;
}
case 1:
{
pools_b.allocate();
SIZE += sizeof(B);
break;
}
case 2:
{
pools_c.allocate();
SIZE += sizeof(C);
break;
}
case 3:
{
pools_d.allocate();
SIZE += sizeof(D);
break;
}
case 4:
{
pools_e.allocate();
SIZE += sizeof(E);
break;
}
}
}
int main(int argc, char** argv)
{
auto t = clock();
for (int i = 0; i < 1000 * 10000; i++)
tt();
cout << "time: " << (clock() - t) << endl;
cout << SIZE / (1024 * 1024) << endl;
getchar();
return 0;
}
#endif
object pool
最新推荐文章于 2023-11-28 22:53:33 发布
该代码实现了一个对象池类(ObjectPool),用于提高内存分配效率。通过memalign_alloc和memalign_free函数处理对齐内存分配和释放。对象池在内存密集型操作中可以避免频繁的新建和删除对象的开销。代码中还展示了如何根据随机选择创建不同大小的结构体实例,比较了使用对象池和直接使用new运算符的性能差异。
摘要由CSDN通过智能技术生成