示例#1
0
        public unsafe void DirectPointer(RetainableMemory <int> rm)
        {
            var  rounds = 1_000;
            long sum    = 0;

            using (Benchmark.Run("DirectPointer", rm.Length * rounds))
            {
                var head = rm.Length / 2;
                var len  = rm.Length;
                var ptr  = (int *)rm.Pointer;

                for (int r = 0; r < rounds; r++)
                {
                    for (int i = 0; i < len; i++)
                    {
                        sum += ptr[i];
                    }
                }
            }

            if (sum < 1000)
            {
                throw new InvalidOperationException();
            }
        }
示例#2
0
        public void MemoryAccessVecViaDbVecStorageUnsafe(RetainableMemory <int> rm)
        {
            var  rounds = TestUtils.GetBenchCount(100_000, 100);
            long sum    = 0;

            using (Benchmark.Run("DbVecStorageUnsafe (+)", rm.Length * rounds))
            {
                DataBlockLike db = new DataBlockLike {
                    Rm = rm, Vec = rm.GetVec().AsVec(), RetainedVec = RetainedVec.Create(rm, 0, rm.Length, true)
                };

                for (int r = 0; r < rounds; r++)
                {
                    for (long i = 0; i < rm.Length; i++)
                    {
                        sum += db.RetainedVec.Vec.UnsafeGetUnaligned <int>((IntPtr)i);
                    }
                }
            }

            if (sum < 1000)
            {
                throw new InvalidOperationException();
            }
        }
示例#3
0
        public unsafe void RingVecUtilIndexToOffset(RetainableMemory <int> rm)
        {
            var  rounds = 1_000;
            long sum    = 0;

            using (Benchmark.Run("RingVecUtil", rm.Length * rounds))
            {
                var head = rm.Length / 2;
                var len  = rm.Length;
                var ptr  = (int *)rm.Pointer;

                for (int r = 0; r < rounds; r++)
                {
                    for (int i = 0; i < len; i++)
                    {
                        sum += ptr[RingVecUtil.IndexToOffset(i, head, len)];
                    }
                }
            }

            if (sum < 1000)
            {
                throw new InvalidOperationException();
            }
        }
示例#4
0
        public static VectorStorage Create <T>(RetainableMemory <T> memorySource,
                                               int memoryStart,
                                               int memoryLength,
                                               int stride           = 1,
                                               int elementLength    = -1,
                                               bool externallyOwned = false)
        {
            Debug.Assert(stride > 0);

            var vs = ObjectPool.Allocate();

            vs._memorySource = memorySource;

            if (!externallyOwned)
            {
                vs._memoryHandle = vs._memorySource.Pin(0);
            }

            vs._vec = memorySource.Vec.AsVec().Slice(memoryStart, memoryLength);

            vs._stride = stride;

            var numberOfStridesFromZero = vs._vec.Length / stride;

            if (stride > 1)
            {
                // last full stride could be incomplete but with the current logic we will access only the first element
                if (vs._vec.Length - numberOfStridesFromZero * stride > 0)
                {
                    numberOfStridesFromZero++;
                }
            }

            if (elementLength != -1)
            {
                if ((uint)elementLength <= numberOfStridesFromZero)
                {
                    numberOfStridesFromZero = elementLength;
                }
                else
                {
                    ThrowHelper.ThrowArgumentOutOfRangeException("elementLength");
                }
            }

            vs._length = numberOfStridesFromZero;

            return(vs);
        }
示例#5
0
        public void MemoryAccessVecViaFieldDangerous(RetainableMemory <int> rm)
        {
            long sum = 0;

            using (Benchmark.Run("FieldUnsafe", rm.Length))
            {
                for (long i = 0; i < rm.Length; i++)
                {
                    sum += rm.Vec.UnsafeGetUnaligned <int>((IntPtr)i);
                }
            }

            if (sum < 1000)
            {
                throw new InvalidOperationException();
            }
        }
示例#6
0
        public void MemoryAccessVecViaLocalDangerous(RetainableMemory <int> rm)
        {
            long sum = 0;

            using (Benchmark.Run("LocalDangerous", rm.Length))
            {
                var vec = rm.Vec;
                for (int i = 0; i < rm.Length; i++)
                {
                    sum += vec.DangerousGetUnaligned <int>(i);
                }
            }

            if (sum < 1000)
            {
                throw new InvalidOperationException();
            }
        }
示例#7
0
        public void MemoryFieldBench_Field(RetainableMemory <int> rm)
        {
            var  rounds = TestUtils.GetBenchCount(100_000_000, 1000);
            long sum    = 0;

            using (Benchmark.Run("Field", rounds))
            {
                for (int r = 0; r < rounds; r++)
                {
                    sum += rm.Memory.Length;
                }
            }

            if (sum < 1000)
            {
                throw new InvalidOperationException();
            }
        }
示例#8
0
        public unsafe void MemoryAccessViaPointer(RetainableMemory <int> rm)
        {
            long sum = 0;

            using (Benchmark.Run("Pointer", rm.Length))
            {
                var ptr = (int *)rm.Pointer;
                for (int i = 0; i < rm.Length; i++)
                {
                    sum += ptr[i];
                }
            }

            if (sum < 1000)
            {
                throw new InvalidOperationException();
            }
        }
示例#9
0
        public void MemoryAccessVecViaHelperUnsafe(RetainableMemory <int> rm)
        {
            long sum = 0;

            using (Benchmark.Run("HelperUnsafe", rm.Length))
            {
                object obj = rm;
                for (long i = 0; i < rm.Length; i++)
                {
                    sum += RetainableMemoryHelper.GetVecRef(obj).UnsafeGetUnaligned <int>((IntPtr)i);
                }
            }

            if (sum < 1000)
            {
                throw new InvalidOperationException();
            }
        }
示例#10
0
        public unsafe void MemoryAccessViaPointer(RetainableMemory <int> rm)
        {
            var  rounds = TestUtils.GetBenchCount(100_000, 100);
            long sum    = 0;

            using (Benchmark.Run("Pointer", rm.Length * rounds))
            {
                var ptr = (int *)rm.Pointer;
                for (int r = 0; r < rounds; r++)
                {
                    for (long i = 0; i < rm.Length; i++)
                    {
                        sum += ptr[i];
                    }
                }
            }

            // if (sum < 1000)
            //     throw new InvalidOperationException();
        }
示例#11
0
        public void MemoryAccessVecViaDbVecStorageDangerous(RetainableMemory <int> rm)
        {
            long sum = 0;

            using (Benchmark.Run("DbVecStorageDangerous (_)", rm.Length))
            {
                DataBlockLike db = new DataBlockLike {
                    Rm = rm, Vec = rm.Vec, VecStorage = VecStorage.Create(rm, 0, rm.Length, true)
                };
                for (int i = 0; i < rm.Length; i++)
                {
                    sum += db.VecStorage.Vec.DangerousGetUnaligned <int>(i);
                }
            }

            if (sum < 1000)
            {
                throw new InvalidOperationException();
            }
        }
示例#12
0
        public unsafe void MemoryAccessVecViaDbVecPointer(RetainableMemory <int> rm)
        {
            long sum = 0;

            using (Benchmark.Run("DbVecPointer (*)", rm.Length))
            {
                DataBlockLike db = new DataBlockLike {
                    Rm = rm, Vec = rm.Vec, Ptr = (int *)rm.Pointer
                };
                for (int i = 0; i < rm.Length; i++)
                {
                    sum += Unsafe.ReadUnaligned <int>(ref Unsafe.As <int, byte>(ref Unsafe.Add <int>(ref Unsafe.AsRef <int>((void *)db.Vec._byteOffset), i)));
                }
            }

            if (sum < 1000)
            {
                throw new InvalidOperationException();
            }
        }
示例#13
0
        public void MemoryAccessVecViaDbVecUnsafe(RetainableMemory <int> rm)
        {
            long sum = 0;

            using (Benchmark.Run("DbVecUnsafe (+)", rm.Length))
            {
                DataBlockLike db = new DataBlockLike {
                    Rm = rm, Vec = rm.Vec
                };
                for (long i = 0; i < rm.Length; i++)
                {
                    sum += db.Vec.UnsafeGetUnaligned <int>((IntPtr)i);
                }
            }

            if (sum < 1000)
            {
                throw new InvalidOperationException();
            }
        }
示例#14
0
        public void MemoryAccessVecViaDbHelperUnsafeGetRef(RetainableMemory <int> rm)
        {
            long          sum = 0;
            DataBlockLike db  = new DataBlockLike {
                Rm = rm, Vec = rm.Vec
            };

            using (Benchmark.Run("DbHelperUnsafeGet (^)", rm.Length))
            {
                for (long i = 0; i < rm.Length; i++)
                {
                    sum += Unsafe.As <PrivateMemory <byte> >(db.Rm).Vec.UnsafeGetUnaligned <int>((IntPtr)i);
                }
            }

            if (sum < 1000)
            {
                throw new InvalidOperationException();
            }
        }
示例#15
0
        public void MemoryAccessVecViaDbHelperDangerous(RetainableMemory <int> rm)
        {
            long sum = 0;

            using (Benchmark.Run("DbHelperDangerous (^)", rm.Length))
            {
                DataBlockLike db = new DataBlockLike {
                    Rm = rm
                };
                for (int i = 0; i < rm.Length; i++)
                {
                    sum += RetainableMemoryHelper.GetVecRef(db.Rm).DangerousGetUnaligned <int>(i);
                }
            }

            if (sum < 1000)
            {
                throw new InvalidOperationException();
            }
        }
示例#16
0
        public void MemoryAccessVecViaMemSpan(RetainableMemory <int> rm)
        {
            var  rounds = TestUtils.GetBenchCount(10_000, 100);
            long sum    = 0;

            using (Benchmark.Run("MemSpan", rm.Length * rounds))
            {
                for (int r = 0; r < rounds; r++)
                {
                    for (long i = 0; i < rm.Length; i++)
                    {
                        sum += rm.Memory.Span[(int)i];
                    }
                }
            }

            if (sum < 1000)
            {
                throw new InvalidOperationException();
            }
        }
示例#17
0
        public void Sum(RetainableMemory <int> rm)
        {
            var rounds = TestUtils.GetBenchCount(100_000, 100);

            long sum = 0;

            using (Benchmark.Run("Sum (CPU Hz)", rm.Length * rounds))
            {
                for (int r = 0; r < rounds; r++)
                {
                    for (long i = 0; i < rm.Length; i++)
                    {
                        sum += i;
                    }
                }
            }

            if (sum < 1000)
            {
                throw new InvalidOperationException();
            }
        }
示例#18
0
        public void MemoryAccessVecViaLocalUnsafe(RetainableMemory <int> rm)
        {
            var  rounds = TestUtils.GetBenchCount(10_000, 100);
            long sum    = 0;

            using (Benchmark.Run("LocalUnsafe", rm.Length * rounds))
            {
                var vec = rm.GetVec().AsVec();
                for (int r = 0; r < rounds; r++)
                {
                    for (long i = 0; i < rm.Length; i++)
                    {
                        sum += vec.UnsafeGetUnaligned <int>((IntPtr)i);
                    }
                }
            }

            if (sum < 1000)
            {
                throw new InvalidOperationException();
            }
        }
示例#19
0
        public unsafe void MemoryAccessViaArray(RetainableMemory <int> rm, int[] arr)
        {
            var           rounds = TestUtils.GetBenchCount(100_000, 100);
            DataBlockLike db     = new DataBlockLike {
                Rm = rm, arr = arr
            };
            long sum = 0;

            using (Benchmark.Run("Array", rm.Length * rounds))
            {
                for (int r = 0; r < rounds; r++)
                {
                    for (int i = 0; i < db.arr.Length; i++)
                    {
                        sum += db.arr[i];
                    }
                }
            }

            if (sum < 1000)
            {
                throw new InvalidOperationException();
            }
        }
示例#20
0
        public unsafe void MemoryAccessVecViaDbVecPointer(RetainableMemory <int> rm)
        {
            var  rounds = TestUtils.GetBenchCount(100_000, 100);
            long sum    = 0;

            using (Benchmark.Run("DbVecPointer (*)", rm.Length * rounds))
            {
                DataBlockLike db = new DataBlockLike {
                    Rm = rm, Vec = rm.GetVec().AsVec(), Ptr = (int *)rm.Pointer
                };
                for (int r = 0; r < rounds; r++)
                {
                    for (long i = 0; i < rm.Length; i++)
                    {
                        sum += Unsafe.ReadUnaligned <int>(ref Unsafe.As <int, byte>(ref Unsafe.Add <int>(ref Unsafe.AsRef <int>((void *)db.Vec._byteOffset), (IntPtr)i)));
                    }
                }
            }

            if (sum < 1000)
            {
                throw new InvalidOperationException();
            }
        }
示例#21
0
        public void MemoryAccessVecViaDbVecDangerous(RetainableMemory <int> rm)
        {
            long sum    = 0;
            var  rounds = TestUtils.GetBenchCount(10_000, 100);

            using (Benchmark.Run("DbVecDangerous (+)", rm.Length * rounds))
            {
                DataBlockLike db = new DataBlockLike {
                    Rm = rm, Vec = rm.GetVec().AsVec()
                };
                for (int r = 0; r < rounds; r++)
                {
                    for (int i = 0; i < rm.Length; i++)
                    {
                        sum += db.Vec.DangerousGetUnaligned <int>(i);
                    }
                }
            }

            if (sum < 1000)
            {
                throw new InvalidOperationException();
            }
        }
示例#22
0
        internal int SeriesIncreaseCapacity <TKey, TValue>(int newCapacity = -1)
        {
            EnsureSeriesLayout();
            EnsureNotSentinel();

            // TODO handle OutOfMemory in RentMemory, operation must be atomic in a sense that any error does not change existing data, no partial updates.

            // TODO _rowIndex.Vec.Length could be already 2x larger because array pool could have returned larger array on previous doubling
            // TODO (!, new) VS now hides total capacity of RM, we could get RM by casting and here we have types.
            // But is it always true that unused part of RM is always free and we could just expand to it without copying?

            // We ignore this now
            //if (_rowIndex.Vec.Length != _rowIndex.Length)
            //{
            //    Console.WriteLine($"_rowIndex.Vec.Length {_rowIndex.Vec.Length} != _rowIndex.Length {_rowIndex.Length}");
            //}

            var ri   = _rowKeys;
            var vals = _values;

            var minCapacity = Math.Max(newCapacity, Settings.MIN_POOLED_BUFFER_LEN);
            var newLen      = Math.Max(minCapacity, BitUtil.FindNextPositivePowerOfTwo(ri.Vec.Length + 1));

            RetainableMemory <TKey>?newRiBuffer = null;
            VecStorage newRi = default;
            RetainableMemory <TValue>?newValsBuffer = null;
            VecStorage newVals = default;

            try
            {
                newRiBuffer = BufferPool <TKey> .MemoryPool.RentMemory(newLen);

                newRi = VecStorage.Create(newRiBuffer, 0, newRiBuffer.Length); // new buffer could be larger
                if (ri.Vec.Length > 0)
                {
                    ri.Vec.AsSpan <TKey>().CopyTo(newRi.Vec.AsSpan <TKey>());
                }

                newValsBuffer = BufferPool <TValue> .MemoryPool.RentMemory(newLen);

                newVals = VecStorage.Create(newValsBuffer, 0, newValsBuffer.Length);
                if (vals.Vec.Length > 0)
                {
                    vals.Vec.AsSpan <TValue>().CopyTo(newVals.Vec.AsSpan <TValue>());
                }
            }
            catch (OutOfMemoryException)
            {
                if (newRi != default)
                {
                    newRi.Dispose();
                }
                else
                {
                    newRiBuffer?.DecrementIfOne();
                }

                if (newVals != default)
                {
                    newVals.Dispose();
                }
                else
                {
                    newValsBuffer?.DecrementIfOne();
                }

                // TODO log this event
                return(-1);
            }

            try
            {
                try
                {
                }
                finally
                {
                    // we have all needed buffers, must switch in one operation

                    _rowKeys = newRi;
                    _values  = newVals;

                    ri.Dispose();
                    vals.Dispose();
                }

                return(_rowKeys.Vec.Length);
            }
            catch
            {
                return(-1);
            }
        }