object pool

该代码实现了一个对象池类(ObjectPool),用于提高内存分配效率。通过memalign_alloc和memalign_free函数处理对齐内存分配和释放。对象池在内存密集型操作中可以避免频繁的新建和删除对象的开销。代码中还展示了如何根据随机选择创建不同大小的结构体实例,比较了使用对象池和直接使用new运算符的性能差异。
摘要由CSDN通过智能技术生成
#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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值