Пример #1
0
 /// <summary>
 /// Broadcasts a network level message to all in the lobby.
 ///
 /// Note: this is (usually) different form sending a lobby message
 /// which is also broadcast to all other remote users in the lobby.
 ///
 /// In general, the msg buffer does not need to live longer than the
 /// duration of the call. It's contents will be copied.
 /// </summary>
 /// <param name="msg">the buffer of the message</param>
 /// <param name="reliability">does the message need to be reliably sent</param>
 public void Broadcast(FixedBuffer msg, Reliability reliability = Reliability.Reliable)
 {
     foreach (var member in _members.Values)
     {
         member.SendMessage(msg, reliability: reliability);
     }
 }
Пример #2
0
        public static TransactionId parseTransactionId(byte[] transactionId)
        {
            if (transactionId == null)
            {
                throw new NullReferenceException("transactionId must not be null");
            }
            var buffer  = new FixedBuffer(transactionId);
            var version = buffer.readByte();

            if (version != VERSION)
            {
                throw new Exception("invalid Version");
            }

            var agentId             = buffer.readPrefixedString();
            var agentStartTime      = buffer.readVLong();
            var transactionSequence = buffer.readVLong();

            if (agentId == null)
            {
                return(new TransactionId(agentStartTime, transactionSequence));
            }
            else
            {
                return(new TransactionId(agentId, agentStartTime, transactionSequence));
            }
        }
        public unsafe void Update()
        {
            fixed(byte *ptr = _readBuffer)
            {
                uint    dataSize = 0u;
                SteamId userId   = 0UL;

                while (SteamNetworking.ReadP2PPacket(_readBuffer, ref dataSize, ref userId))
                {
                    var handle  = new AccountHandle(userId);
                    var handled = false;
                    foreach (var lobby in _connectedLobbies.Values)
                    {
                        if (lobby.Members.TryGetValue(handle, out LobbyMember member))
                        {
                            var buffer = new FixedBuffer(ptr, dataSize);
                            member.DispatchNetworkMessage(buffer);
                            handled = true;
                        }
                    }
                    if (!handled)
                    {
                        Debug.LogWarning($"[Steam] Unexpected network message from user: {userId}");
                    }
                }
            }
        }
Пример #4
0
 /// <summary>
 /// Creates a Deserializer from a provided FixedBuffer.
 /// </summary>
 public static Deserializer Create(FixedBuffer buf)
 {
     return(new Deserializer {
         _start = buf.Start,
         _current = buf.Start,
         _end = buf.End,
     });
 }
Пример #5
0
        public void FragmentNativeHeap()
        {
            Info($"Dirty decay time: {Jem.GetMallCtlSInt64("arenas.dirty_decay_ms")} ms");
            int largeBlockSize = InitialLargeBlockSize;
            SafeArray <FixedBuffer <T> > smallBlocks = new SafeArray <FixedBuffer <T> >(LoopCount);
            int             i        = 0;
            FixedBuffer <T> bigBlock = default;

            try
            {
                for (i = 0; i < LoopCount; i++)
                {
                    bigBlock = new FixedBuffer <T>(largeBlockSize);
                    FixedBuffer <T> smallBlock = new FixedBuffer <T>(SmallBlockSize);
                    int             j          = JemUtil.Rng.Next(0, ArraySize);
                    T r = GM <T> .Random();

                    smallBlock[j]  = r;
                    smallBlocks[i] = smallBlock;
                    if (!smallBlocks[i][j].Equals(r))
                    {
                        throw new Exception($"Cannot validate small block at index {i}.");
                    }
                    if (!bigBlock.Free())
                    {
                        throw new Exception("Cannot free bigBlock.");
                    }
                    largeBlockSize = largeBlockSize + (1 * 1024 * 1024);
                }
                this.SetStatistic($"{nameof(FragmentNativeHeap)}_WorkingSet", JemUtil.PrintBytes(JemUtil.ProcessWorkingSet));
                this.SetStatistic($"{nameof(FragmentNativeHeap)}_JemResident", JemUtil.PrintBytes(Jem.ResidentBytes));
                this.SetStatistic($"{nameof(FragmentNativeHeap)}_PrivateMemory", JemUtil.PrintBytes(JemUtil.ProcessPrivateMemory));
                this.SetStatistic($"{nameof(FragmentNativeHeap)}_JemAllocated", JemUtil.PrintBytes(Jem.AllocatedBytes));
                foreach (FixedBuffer <T> b in smallBlocks)
                {
                    if (!b.Free())
                    {
                        throw new Exception($"Cannot free small block at index {i}.");
                    }
                }
            }
            catch (OutOfMemoryException)
            {
                Info(Jem.MallocStats);
                Error($"Out-of-Memory at index {i} with large block size {largeBlockSize}.");
                foreach (FixedBuffer <T> b in smallBlocks)
                {
                    b.Free();
                }
                throw;
            }
            finally
            {
                GC.Collect();
            }
        }
Пример #6
0
 private Queue <SendCommond> cmdQueue = new Queue <SendCommond>(); //指令发送队列
 public TcpPacketProtocol(int bufferSize, int bufferPoolSize, ILoger loger)
 {
     this.loger = loger;
     if (BufferPool == null)
     {
         BufferPool = new FixedBufferPool(bufferSize, bufferPoolSize);
     }
     ReceiveBuffers = new Queue <IFixedBuffer>();
     SendBuffer     = new FixedBuffer(bufferPoolSize);
 }
Пример #7
0
 internal void SendLobbyMessage(AccountHandle source, FixedBuffer msg)
 {
     foreach (var view in _connectedViews.Values)
     {
         if (view.Members.TryGetValue(source, out LobbyMember member))
         {
             view.DispatchLobbyMessage(member, msg);
         }
     }
 }
Пример #8
0
        static unsafe void Main(string[] args)
        {
            // almost no effect on compression ration when above 10000
            // main effect on memory consumption
            var chunkSize = 100000;
            var date      = new DateTime(2015, 8, 5);
            var fb        = new FixedBuffer();
            var tsize     = Marshal.SizeOf(typeof(TaqTrade));

            Console.WriteLine(tsize);

            var zip    = ZipFile.OpenRead(path);
            var stream = zip.Entries.Single().Open();

            using (var reader = new StreamReader(stream, Encoding.ASCII))
                using (var bReader = new BinaryReader(stream, Encoding.ASCII)) {
                    byte[] compressedBuffer = null;
                    var    byteBuffer       = new byte[106];
                    var    tradesArray      = new TaqTrade[chunkSize];
                    var    line             = reader.ReadLine();
                    Console.WriteLine(line);
                    Console.WriteLine("Press enter to continue");
                    Console.ReadLine();
                    var sw = new Stopwatch();
                    sw.Start();
                    var c = 0;
                    while (!reader.EndOfStream) // && c < 100
                    // these two lines take 57% time
                    {
                        line = reader.ReadLine();
                        Encoding.ASCII.GetBytes(line, 0, 106, byteBuffer, 0);

                        fb.Wrap(byteBuffer);
                        var trade = new TaqTrade(date, fb);
                        tradesArray[c % chunkSize] = trade;

                        c++;
                        if (c % chunkSize == 0)
                        {
                            var comrpessed       = Serializer.Serialize(tradesArray);
                            var averageComprSize = comrpessed.Length * 1.0 / chunkSize;
                            var ratio            = (106.0 * chunkSize) / (comrpessed.Length * 1.0);
                            //Console.WriteLine(line);
                            Console.WriteLine($"Read so far: {c}, ratio: {ratio}, comp size: {averageComprSize}");
                            //Console.WriteLine("Press enter to continue");
                            //Console.ReadLine();
                        }
                    }
                    sw.Stop();
                    Console.WriteLine($"Lines read: ${c} in msecs: {sw.ElapsedMilliseconds}");
                }

            Console.WriteLine("Finished");
            Console.ReadLine();
        }
Пример #9
0
        public void CanVectorizeMandelbrotUnmanaged()
        {
            FixedBuffer <byte> output = new FixedBuffer <byte>(Mandelbrot_Height * Mandelbrot_Width);
            FixedBuffer <byte> o      = _Mandelbrotv2Unmanaged(ref output);

            Assert.Equal(0, o[0]);
            Assert.Equal(2, o[1000]);
            Assert.Equal(10, o[500]);
            WriteMandelbrotPPM(o.CopyToArray(), "mandelbrot_unmanaged.ppm");
            o.Free();
        }
Пример #10
0
        // TODO! test if this is the same as reading directly from fb, endianness could affect this
        public UUID(byte[] bytes)
        {
            if (bytes == null || bytes.Length < 16)
            {
                throw new ArgumentException("bytes == null || bytes.Length < 16", nameof(bytes));
            }
            var fb = new FixedBuffer(bytes);

            _first  = fb.ReadUint64(0);
            _second = fb.ReadUint64(8);
        }
Пример #11
0
        private FixedBuffer <int> Mandelbrotv1Unmanaged()
        {
            SafeArray <Vector <float> > Vectors = new SafeArray <Vector <float> >(8);                                      // New unmanaged array of vectors
            FixedBuffer <int>           output  = new FixedBuffer <int>(((int)Mandelbrot_Width * (int)Mandelbrot_Height)); //New unmanaged array for bitmap output
            Span <float>   VectorSpan           = Vectors.GetSpan <float>();                                               //Lets us write to individual vector elements
            Span <Vector2> Vector2Span          = Vectors.GetSpan <Vector2>();                                             //Lets us read to individual vectors

            VectorSpan[0] = -2f;
            VectorSpan[1] = -1f;
            VectorSpan[2] = 1f;
            VectorSpan[3] = 1f;
            VectorSpan[4] = Mandelbrot_Width;
            VectorSpan[5] = Mandelbrot_Height;

            ref Vector2 C0 = ref Vector2Span[0];
Пример #12
0
 private ConcurrentQueue <SendData> sendDataQueue = new ConcurrentQueue <SendData>(); //指令发送队列
 public TcpClientPacketProtocol(int bufferSize, int fixedBufferPoolSize)
 {
     if (BufferPool == null)
     {
         lock (closeLock)
         {
             if (BufferPool == null)
             {
                 BufferPool = new FixedBufferPool(fixedBufferPoolSize, bufferSize);
             }
         }
     }
     ReceiveBuffers    = new Queue <IFixedBuffer>();
     SendBuffer        = new FixedBuffer(bufferSize);
     ReceiveDataBuffer = new DynamicBuffer(bufferSize);
 }
Пример #13
0
        internal void SendNetworkMessage(AccountHandle source, AccountHandle target, FixedBuffer msg, Reliability reliability)
        {
            // Simulate unreliablity
            if (reliability == Reliability.Unreliable && _packetLossRng.NextDouble() > _packetLossPercent)
            {
                return;
            }
            LocalLobbyView view;
            LobbyMember    member;

            if (!_connectedViews.TryGetValue(target, out view) ||
                !view.Members.TryGetValue(source, out member))
            {
                return;
            }
            member.DispatchNetworkMessage(msg);
        }
Пример #14
0
        public void Test1()
        {
            int count = 0;

            while (count < 10)
            {
                FixedBuffer <int> b = new FixedBuffer <int>(JemUtil.Rng.Next(100000, 1000000));
                int r = JemUtil.Rng.Next(0, 64);
                b.Fill(r);
                for (int i = 0; i < b.Length; i++)
                {
                    Assert.Equal(r, b[i]);
                }
                Assert.True(b.Free());
                count++;
            }
        }
Пример #15
0
        static void Main(string[] args)
        {
            byte xx = 10;
            byte yy = xx;

            unsafe
            {
                byte *p1 = &xx;
                byte *p2 = &yy;
                Console.WriteLine((int)p1 + "  " + (int)p2);
            }
            xx = 20;
            unsafe
            {
                byte *p1 = &xx;
                Console.WriteLine((int)p1);
            }

            Console.WriteLine("--------指针转换-------");
            PointConvert();
            Console.WriteLine("--------指针寻址的值--------");
            PointValue();
            Console.WriteLine("---------指针的运算1----------");
            PointCalculate();
            Console.WriteLine("------指针的运算2------");
            PointCalculate2();
            Console.WriteLine("-----指针的运算3------");
            PointCalculate3();
            Console.WriteLine("------指针运算4------");
            PointCalculate4();
            Console.WriteLine("-----指针运算5-----");
            PointCalculate5();
            Console.WriteLine("-------指针运算6--------");
            PointCalculate6();
            Console.WriteLine("----大小端问题----");
            PointandMemory.MemoryOrderInt();
            Console.WriteLine("------大小端问题-------");
            PointandMemory.MemoryOrderIntArr();
            Console.WriteLine("-------固定缓冲区大小-------");
            FixedBuffer.Test();
            Console.Read();
        }
        public void Equal()
        {
            var buffer    = new FixedBuffer();
            var container = new BoxingContainer <FixedBuffer>(buffer, FixedBuffer.Length);

            unsafe
            {
                fixed(char *ptr = container.Data.fixedBuffer)
                {
                    *ptr = 'A';
                }

                container.Data.fixedBuffer[0].Should().Be('A');

                var index = container.Length - 1;

                container.Data.fixedBuffer[index] = 'B';
                container.Data.fixedBuffer[index].Should().Be('B');
            }
        }
Пример #17
0
        /// <summary>
        /// Sends a message to the user over the network.
        ///
        /// In general, the msg buffer does not need to live longer than the
        /// duration of the call. It's contents will be copied.
        /// </summary>
        /// <param name="msg">the buffer of the message</param>
        /// <param name="size">the size of the message, uses the size of the buffer if negative.</param>
        /// <param name="reliability">does the message need to be reliably sent</param>
        public unsafe void SendMessage(FixedBuffer msg, Reliability reliability = Reliability.Reliable)
        {
            if (MessageProcessor == null)
            {
                Lobby.SendNetworkMessage(Id, msg, reliability: reliability);
            }
            else
            {
                var buffer = msg.ToArray();
                var size   = (int)msg.Size;
                MessageProcessor.Apply(ref buffer, ref size);
                fixed(byte *ptr = buffer)
                {
                    msg = new FixedBuffer(ptr, size);
                    Lobby.SendNetworkMessage(Id, msg, reliability: reliability);
                }
            }

            _stats.PacketsSent++;
            _stats.BytesSent += (ulong)msg.Size;
        }
Пример #18
0
        public TaqTrade(DateTime date, FixedBuffer fb)
        {
            // Read<> over fb is much slower
            var db = fb;

            // Time
            _timeUTCTicks = ReadHHMMSSXXXXXXAsUtcTicks(date, fb, 0);
            // Exchange
            Exchange = fb.ReadByte(12);
            // Symbol
            fixed(void *ptr = _symbol)
            {
                fb.Copy((IntPtr)ptr, 13, 16);
            }

            // Sale Condition
            fixed(void *ptr = _saleCondition)
            {
                fb.Copy((IntPtr)ptr, 29, 4);
            }

            TradeVolume             = (uint)ReadUInt64(fb, 33, 9);
            TradePrice              = ReadUInt64(fb, 42, 11);
            TradeStopStockIndicator = db.ReadByte(53);

            TradeCorrectionIndicator = (byte)ReadUInt64(fb, 54, 2);
            TradeSequenceNumber      = ReadUInt64(fb, 56, 16);
            SourceOfTrade            = db.ReadByte(72);
            TradeReportingFacility   = db.ReadByte(73);

            _participantTimestampUtcTicks = ReadHHMMSSXXXXXXAsUtcTicks(date, fb, 74);

            fixed(void *ptr = _rnn)
            {
                fb.Copy((IntPtr)ptr, 86, 8);
            }

            _TRFTimestampUtcTicks = ReadHHMMSSXXXXXXAsUtcTicks(date, fb, 94);
        }
Пример #19
0
        public unsafe void CouldCatchErrorWhileWritingPastBoundary()
        {
            // This doesn;t throw unless size is 4096 vs 12
            // Could not make any assumptions that it is safe to write past boundary
            // with try..catch. Even byte[] allows it and we probably corrupt
            // .NETs memory next to it.
            var bytes = new byte[12];
            var fb    = new FixedBuffer(bytes);

            fixed(byte *ptr = &bytes[10])
            {
                *(long *)(ptr) = long.MaxValue;
            }

            var df = new DirectFile("../CouldCatchErrorWhileWritingPastBoundary", 12);

            *(long *)(df.Buffer.Data + 10) = long.MaxValue;
            df.Dispose();
            var df2 = new DirectFile("../CouldCatchErrorWhileWritingPastBoundary", 12);

            Assert.AreEqual(long.MaxValue, *(long *)(df2.Buffer.Data + 10));
        }
Пример #20
0
        internal unsafe void DispatchNetworkMessage(FixedBuffer msg)
        {
            _stats.PacketsRecieved++;
            _stats.BytesRecieved += (ulong)msg.Size;

            if (OnNetworkMessage == null)
            {
                return;
            }
            if (MessageProcessor == null)
            {
                OnNetworkMessage(msg);
            }
            else
            {
                var buffer = msg.ToArray();
                var size   = (int)msg.Size;
                MessageProcessor.Unapply(ref buffer, ref size);
                fixed(byte *ptr = buffer)
                {
                    OnNetworkMessage(new FixedBuffer(ptr, size));
                }
            }
        }
Пример #21
0
        public void ArrayVsListVsIList()
        {
            var len = 1000;

            var arr = new double[len];

            var buffer      = new byte[len * 8];
            var fixedBuffer = new FixedBuffer(buffer);

            var unmanagedMemory = Marshal.AllocHGlobal(len * 8);
            var directBuffer    = new DirectBuffer(len * 8, unmanagedMemory);

            for (int i = 0; i < len; i++)
            {
                arr[i] = i;
                fixedBuffer.WriteDouble(i * 8, i);
                directBuffer.WriteDouble(i * 8, i);
            }
            var list = new List <double>(arr);

            var ilist = list as IList <double>;

            var idxs = new int[len / 10];
            var rng  = new System.Random();

            for (int i = 0; i < idxs.Length; i++)
            {
                idxs[i] = rng.Next(0, len);
            }

            var sum = 0.0;

            var maxRounds = 100000;

            using (Benchmark.Run("Array", len * maxRounds / 10))
            {
                sum = 0.0;
                for (int rounds = 0; rounds < maxRounds; rounds++)
                {
                    foreach (var idx in idxs)
                    {
                        sum += arr[idx];
                    }
                }
            }

            using (Benchmark.Run("List", len * maxRounds / 10))
            {
                sum = 0.0;
                for (int rounds = 0; rounds < maxRounds; rounds++)
                {
                    foreach (var idx in idxs)
                    {
                        sum += list[idx];
                    }
                }
            }

            using (Benchmark.Run("LockedList", len * maxRounds / 10))
            {
                sum = 0.0;
                for (int rounds = 0; rounds < maxRounds; rounds++)
                {
                    foreach (var idx in idxs)
                    {
                        lock (list)
                        {
                            sum += list[idx];
                        }
                    }
                }
            }

            using (Benchmark.Run("SpinLockedList", len * maxRounds / 10))
            {
                sum = 0.0;
                SpinLock sl = new SpinLock();
                for (int rounds = 0; rounds < maxRounds; rounds++)
                {
                    foreach (var idx in idxs)
                    {
                        bool gotLock = false;
                        gotLock = false;
                        try
                        {
                            sl.Enter(ref gotLock);
                            sum += list[idx];
                        }
                        finally
                        {
                            // Only give up the lock if you actually acquired it
                            if (gotLock)
                            {
                                sl.Exit();
                            }
                        }
                    }
                }
            }

            using (Benchmark.Run("InterLockedList", len * maxRounds / 10))
            {
                sum = 0.0;
                var counter = 0L;
                for (int rounds = 0; rounds < maxRounds; rounds++)
                {
                    foreach (var idx in idxs)
                    {
                        var dummy = Interlocked.CompareExchange(ref counter, idx, 0L);
                        sum += list[idx] + dummy;
                    }
                }
            }

            using (Benchmark.Run("IList", len * maxRounds / 10))
            {
                sum = 0.0;
                for (int rounds = 0; rounds < maxRounds; rounds++)
                {
                    foreach (var idx in idxs)
                    {
                        sum += ilist[idx];
                    }
                }
            }

            using (Benchmark.Run("FixedBuffer", len * maxRounds / 10))
            {
                sum = 0.0;
                for (int rounds = 0; rounds < maxRounds; rounds++)
                {
                    foreach (var idx in idxs)
                    {
                        sum += fixedBuffer.ReadDouble(idx * 8);
                    }
                }
            }

            using (Benchmark.Run("IFixedBuffer", len * maxRounds / 10))
            {
                sum = 0.0;
                var ifb = fixedBuffer as IDirectBuffer;
                for (int rounds = 0; rounds < maxRounds; rounds++)
                {
                    foreach (var idx in idxs)
                    {
                        sum += ifb.ReadDouble(idx * 8);
                    }
                }
            }

            using (Benchmark.Run("DirectBuffer", len * maxRounds / 10))
            {
                sum = 0.0;
                for (int rounds = 0; rounds < maxRounds; rounds++)
                {
                    foreach (var idx in idxs)
                    {
                        sum += directBuffer.ReadDouble(idx * 8);
                    }
                }
            }

            using (Benchmark.Run("}", len * maxRounds / 10))
            {
                sum = 0.0;
                var idb = directBuffer as IDirectBuffer;
                for (int rounds = 0; rounds < maxRounds; rounds++)
                {
                    foreach (var idx in idxs)
                    {
                        sum += idb.ReadDouble(idx * 8);
                    }
                }
            }
        }
Пример #22
0
        static unsafe void Main(string[] args)
        {
            GC.Collect(3, GCCollectionMode.Forced, true);
            var store = new SeriesStorage(SeriesStorage.GetDefaultConnectionString("TAQSample2.db"));


            var date = new DateTime(2015, 8, 5);

            var tsize = Marshal.SizeOf(typeof(TaqTrade));

            Console.WriteLine(tsize);

            var zip    = ZipFile.OpenRead(path);
            var stream = zip.Entries.Single().Open();

            var seriesDictionary = new Dictionary <string, IPersistentOrderedMap <DateTime, TaqTrade> >();

            using (BufferedStream bs = new BufferedStream(stream, 2 * 1024 * 1024))
                using (var reader = new StreamReader(bs, Encoding.ASCII)) {
                    byte[] compressedBuffer = null;
                    var    byteBuffer       = new byte[106];
                    int    len;
                    var    line = reader.ReadLine();
                    len = bs.ReadLineIntoBuffer(byteBuffer);
                    Console.WriteLine(line);
                    Console.WriteLine("Press enter to continue");
                    Console.ReadLine();
                    var sw = new Stopwatch();
                    sw.Start();
                    var c = 0;
                    while ((len = bs.ReadLineIntoBuffer(byteBuffer)) != 0) // && c < 100
                    {
                        var fb    = new FixedBuffer(byteBuffer, 0, len);
                        var trade = new TaqTrade(date, fb);

                        var symbol = trade.Symbol.ToLowerInvariant().Trim();

                        IPersistentOrderedMap <DateTime, TaqTrade> series;
                        if (!seriesDictionary.TryGetValue(symbol, out series))
                        {
                            series = store.GetPersistentOrderedMap <DateTime, TaqTrade>(symbol);
                            seriesDictionary[symbol] = series;
                        }

                        series[trade.Time] = trade;

                        c++;
                        if (c % 100000 == 0)
                        {
                            Console.WriteLine($"Read so far: {c}");
                            foreach (var s in seriesDictionary)
                            {
                                s.Value.Flush();
                            }
                        }
                    }
                    sw.Stop();
                    foreach (var series in seriesDictionary)
                    {
                        series.Value.Flush();
                    }
                    Console.WriteLine($"Lines read: ${c} in msecs: {sw.ElapsedMilliseconds}");
                }

            Console.WriteLine("Finished");
            GC.Collect(3, GCCollectionMode.Forced, true);
            Console.WriteLine($"Total memory: {GC.GetTotalMemory(true)}");
            Console.ReadLine();
        }
Пример #23
0
 private ConcurrentQueue <byte[]> sendDataQueue = new ConcurrentQueue <byte[]>(); //指令发送队列
 public TcpClientPacketProtocol(int bufferSize, int fixedBufferPoolSize, bool netByteOrder = false)
 {
     SendBuffer        = new FixedBuffer(bufferSize);
     this.NetByteOrder = netByteOrder;
     ReceiveDataBuffer = new DynamicBuffer(bufferSize);
 }
Пример #24
0
 public void CanCreateFixedArray()
 {
     FixedBuffer <byte> buffer = new FixedBuffer <byte>(4096);
     ref byte           z      = ref buffer[0];
Пример #25
0
        public void ArrayVsListVsIList()
        {
            var len = 1000;

            var arr = new double[len];

            var buffer      = new byte[len * 8];
            var fixedBuffer = new FixedBuffer(buffer);

            var unmanagedMemory = Marshal.AllocHGlobal(len * 8);
            var directBuffer    = new DirectBuffer(len * 8, unmanagedMemory);

            for (int i = 0; i < len; i++)
            {
                arr[i] = i;
                fixedBuffer.WriteDouble(i * 8, i);
                directBuffer.WriteDouble(i * 8, i);
            }
            var list = new List <double>(arr);

            var ilist = list as IList <double>;

            var vector = new Spreads.Experimental.Vector <double>(arr);

            vector.IsSynchronized = true;

            var idxs = new int[len / 10];
            var rng  = new System.Random();

            for (int i = 0; i < idxs.Length; i++)
            {
                idxs[i] = rng.Next(0, len);
            }

            var sw  = new Stopwatch();
            var sum = 0.0;

            sw.Start();
            sw.Stop();

            var maxRounds = 100000;

            sw.Restart();
            sum = 0.0;
            for (int rounds = 0; rounds < maxRounds; rounds++)
            {
                foreach (var idx in idxs)
                {
                    sum += arr[idx];
                }
            }
            sw.Stop();
            Console.WriteLine($"Array: {sum}");
            Console.WriteLine($"Elapsed {sw.ElapsedMilliseconds}");
            Console.WriteLine($"Mops {(double)len * maxRounds / sw.ElapsedMilliseconds * 0.0001}");
            Console.WriteLine("---");

            sw.Restart();
            sum = 0.0;
            for (int rounds = 0; rounds < maxRounds; rounds++)
            {
                foreach (var idx in idxs)
                {
                    sum += list[idx];
                }
            }
            sw.Stop();
            Console.WriteLine($"List: {sum}");
            Console.WriteLine($"Elapsed {sw.ElapsedMilliseconds}");
            Console.WriteLine($"Mops {(double)len * maxRounds / sw.ElapsedMilliseconds * 0.0001}");
            Console.WriteLine("---");

            sw.Restart();
            sum = 0.0;
            for (int rounds = 0; rounds < maxRounds; rounds++)
            {
                foreach (var idx in idxs)
                {
                    sum += vector[idx];
                }
            }
            sw.Stop();
            Console.WriteLine($"Vector: {sum}");
            Console.WriteLine($"Elapsed {sw.ElapsedMilliseconds}");
            Console.WriteLine($"Mops {(double)len * maxRounds / sw.ElapsedMilliseconds * 0.0001}");
            Console.WriteLine("---");

            sw.Restart();
            sum = 0.0;
            for (int rounds = 0; rounds < maxRounds; rounds++)
            {
                foreach (var idx in idxs)
                {
                    lock (list)
                    {
                        sum += list[idx];
                    }
                }
            }
            sw.Stop();
            Console.WriteLine($"LockedList: {sum}");
            Console.WriteLine($"Elapsed {sw.ElapsedMilliseconds}");
            Console.WriteLine($"Mops {(double)len * maxRounds / sw.ElapsedMilliseconds * 0.0001}");
            Console.WriteLine("---");

            sw.Restart();
            sum = 0.0;
            SpinLock sl = new SpinLock();

            for (int rounds = 0; rounds < maxRounds; rounds++)
            {
                foreach (var idx in idxs)
                {
                    bool gotLock = false;
                    gotLock = false;
                    try
                    {
                        sl.Enter(ref gotLock);
                        sum += list[idx];
                    }
                    finally
                    {
                        // Only give up the lock if you actually acquired it
                        if (gotLock)
                        {
                            sl.Exit();
                        }
                    }
                }
            }
            sw.Stop();
            Console.WriteLine($"SpinLockedList: {sum}");
            Console.WriteLine($"Elapsed {sw.ElapsedMilliseconds}");
            Console.WriteLine($"Mops {(double)len * maxRounds / sw.ElapsedMilliseconds * 0.0001}");
            Console.WriteLine("---");

            sw.Restart();
            sum = 0.0;
            var counter = 0L;

            for (int rounds = 0; rounds < maxRounds; rounds++)
            {
                foreach (var idx in idxs)
                {
                    var dummy = Interlocked.CompareExchange(ref counter, idx, 0L);
                    sum += list[idx] + dummy;
                }
            }
            sw.Stop();
            Console.WriteLine($"InterLockedList: {sum}");
            Console.WriteLine($"Elapsed {sw.ElapsedMilliseconds}");
            Console.WriteLine($"Mops {(double)len * maxRounds / sw.ElapsedMilliseconds * 0.0001}");
            Console.WriteLine("---");

            sw.Restart();
            sum = 0.0;
            for (int rounds = 0; rounds < maxRounds; rounds++)
            {
                foreach (var idx in idxs)
                {
                    sum += ilist[idx];
                }
            }
            sw.Stop();
            Console.WriteLine($"IList: {sum}");
            Console.WriteLine($"Elapsed {sw.ElapsedMilliseconds}");
            Console.WriteLine($"Mops {(double)len * maxRounds / sw.ElapsedMilliseconds * 0.0001}");
            Console.WriteLine("---");

            sw.Restart();
            sum = 0.0;
            for (int rounds = 0; rounds < maxRounds; rounds++)
            {
                foreach (var idx in idxs)
                {
                    sum += fixedBuffer.ReadDouble(idx * 8);
                }
            }
            sw.Stop();
            Console.WriteLine($"FixedBuffer: {sum}");
            Console.WriteLine($"Elapsed {sw.ElapsedMilliseconds}");
            Console.WriteLine($"Mops {(double)len * maxRounds / sw.ElapsedMilliseconds * 0.0001}");
            Console.WriteLine("---");

            sw.Restart();
            sum = 0.0;
            var ifb = fixedBuffer as IDirectBuffer;

            for (int rounds = 0; rounds < maxRounds; rounds++)
            {
                foreach (var idx in idxs)
                {
                    sum += ifb.ReadDouble(idx * 8);
                }
            }
            sw.Stop();
            Console.WriteLine($"IFixedBuffer: {sum}");
            Console.WriteLine($"Elapsed {sw.ElapsedMilliseconds}");
            Console.WriteLine($"Mops {(double)len * maxRounds / sw.ElapsedMilliseconds * 0.0001}");
            Console.WriteLine("---");

            sw.Restart();
            sum = 0.0;
            for (int rounds = 0; rounds < maxRounds; rounds++)
            {
                foreach (var idx in idxs)
                {
                    sum += directBuffer.ReadDouble(idx * 8);
                }
            }
            sw.Stop();
            Console.WriteLine($"DirectBuffer: {sum}");
            Console.WriteLine($"Elapsed {sw.ElapsedMilliseconds}");
            Console.WriteLine($"Mops {(double)len * maxRounds / sw.ElapsedMilliseconds * 0.0001}");
            Console.WriteLine("---");

            sw.Restart();
            sum = 0.0;
            var idb = directBuffer as IDirectBuffer;

            for (int rounds = 0; rounds < maxRounds; rounds++)
            {
                foreach (var idx in idxs)
                {
                    sum += idb.ReadDouble(idx * 8);
                }
            }
            sw.Stop();
            Console.WriteLine($"IDirectBuffer: {sum}");
            Console.WriteLine($"Elapsed {sw.ElapsedMilliseconds}");
            Console.WriteLine($"Mops {(double)len * maxRounds / sw.ElapsedMilliseconds * 0.0001}");
            Console.WriteLine("---");
        }