3.Garnet 高性能类 - LimitedFixedBufferPool

Garnet使用了大量的指针用于优化性能,这里介绍一下LimitedFixedBufferPool:固定缓冲池

1.PoolEntry


        /// <summary>
        /// Entry
        /// </summary>
        public readonly byte[] entry;

        /// <summary>
        /// Entry pointer
        /// </summary>
        public byte* entryPtr;
        
        /// <summary>
        /// Constructor
        /// </summary>
        public PoolEntry(int size, LimitedFixedBufferPool pool)
        {
            Debug.Assert(pool != null);
            this.pool = pool;
            this.disposed = false;
            entry = GC.AllocateArray<byte>(size, pinned: true);
            entryPtr = (byte*)Unsafe.AsPointer(ref entry[0]);
        }

定义:缓冲池中单个缓冲块,包含一个存储数据的字节数组,以及指向 entry 数组第一个元素的指针,在构造函数分配一个指定大小的内存块,并将其与缓冲池关联

2.PoolLevel


        /// <summary>
        /// Size
        /// </summary>
        public int size;

        /// <summary>
        /// Items
        /// </summary>
        public readonly ConcurrentQueue<PoolEntry> items;

表示缓冲池中的一个级别,每个级别包含一定大小的内存块

3.LimitedFixedBufferPool

固定大小的缓冲池,它管理多个级别的缓冲区,每个级别包含一定数量的预分配的内存块,这个可以有效的减少内存碎片,并降低垃圾回收器的压力,并且使用了Interlocked来确保它的线程安全。


        /// <summary>
        /// Return
        /// </summary>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public void Return(PoolEntry buffer)
        {
            int level = Position(buffer.entry.Length);
            if (level >= 0)
            {
                if (pool[level] != null)
                {
                    if (Interlocked.Increment(ref pool[level].size) <= maxEntriesPerLevel)
                    {
                        Array.Clear(buffer.entry, 0, buffer.entry.Length);
                        pool[level].items.Enqueue(buffer);
                    }
                    else
                        Interlocked.Decrement(ref pool[level].size);
                }
            }
            Debug.Assert(totalAllocations > 0, $"Return with {totalAllocations}");
            Interlocked.Decrement(ref totalAllocations);
        }

        /// <summary>
        /// Get buffer
        /// </summary>
        /// <param name="size"></param>
        /// <returns></returns>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public unsafe PoolEntry Get(int size)
        {
            if (Interlocked.Increment(ref totalAllocations) < 0)
            {
                Interlocked.Decrement(ref totalAllocations);
                logger?.LogError("Invalid Get on disposed pool");
                return null;
            }

            int level = Position(size);
            if (level >= 0)
            {
                if (pool[level] == null)
                {
                    Interlocked.CompareExchange(ref pool[level], new PoolLevel(), null);
                }

                if (pool[level].items.TryDequeue(out var page))
                {
                    Interlocked.Decrement(ref pool[level].size);
                    page.Reuse();
                    return page;
                }
            }
            return new PoolEntry(size, this);
        }

主要包括两个方法 Get:顾名思义就是从缓冲池中获取固定大小的PoolEntry,Return:销毁使用完成的缓冲块。
其他方法 Position:其中对大小进行是否为2的幂的检查,这样做能够更好地与操作系统的内存页大小对齐,这有助于减少内存碎片,并可能提高内存访问速度。
使用:这个类在Garnet处理网络请求中被广泛使用。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值