├── README.md ├── .github └── FUNDING.yml ├── .gitignore ├── DoDSamples ├── DoDSamples.csproj ├── Samples │ ├── Benchmarks │ │ ├── InstructionAndDataDependency.cs │ │ ├── RefListvsList.cs │ │ ├── RowsVsCols.cs │ │ └── OOPvsDoDParsers.cs │ ├── CacheSize.cs │ ├── Utils.cs │ ├── ArrayEnumerableByRef.cs │ ├── POParser │ │ ├── OOPParser_Slow.cs │ │ ├── DoDPOParser_v1a.cs │ │ ├── DoDPOParser_v3a.cs │ │ ├── POGenerator.cs │ │ ├── DoDPOParser_v2a.cs │ │ ├── DoDPOParser_v1.cs │ │ ├── OOPParser_Fast.cs │ │ ├── DoDPOParser_v3.cs │ │ ├── DoDPOParser_v2.cs │ │ ├── DoDPOParser_v5.cs │ │ ├── DoDPOParser_v4.cs │ │ └── Sample.po │ ├── Tests │ │ ├── RowsVsColsTests.cs │ │ └── PoParserTests.cs │ ├── SIMD.cs │ ├── MemoryModelDeadlock.cs │ ├── BlockList.cs │ ├── RefList.cs │ ├── ReferenceHelpers.cs │ ├── SOAwithSIMD.cs │ ├── AOSvsSOA.cs │ ├── InstructionLevelDependency.cs │ └── BitOperations.cs └── Program.cs ├── LICENSE └── DoDSamples.sln /README.md: -------------------------------------------------------------------------------- 1 | # DataOrientedDesign 2 | Sample codes from my Lectures and Trainings on DoD 3 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | custom: ['https://www.buymeacoffee.com/LevelUp'] 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # This .gitignore file was automatically created by Microsoft(R) Visual Studio. 3 | ################################################################################ 4 | 5 | /DoDSamples/bin 6 | /DoDSamples/obj 7 | -------------------------------------------------------------------------------- /DoDSamples/DoDSamples.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | netcoreapp3.1 6 | 7 | 8 | 9 | false 10 | true 11 | x64 12 | 13 | 14 | 15 | true 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | Always 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Bartosz 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /DoDSamples.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.29613.14 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DoDSamples", "DoDSamples\DoDSamples.csproj", "{3EA7FF30-3668-40EE-98A3-AF97EBBAF2EE}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {3EA7FF30-3668-40EE-98A3-AF97EBBAF2EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {3EA7FF30-3668-40EE-98A3-AF97EBBAF2EE}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {3EA7FF30-3668-40EE-98A3-AF97EBBAF2EE}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {3EA7FF30-3668-40EE-98A3-AF97EBBAF2EE}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {C2EF3999-A95E-4F75-93AA-E9BC82B5785F} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /DoDSamples/Samples/Benchmarks/InstructionAndDataDependency.cs: -------------------------------------------------------------------------------- 1 | using BenchmarkDotNet.Attributes; 2 | using BenchmarkDotNet.Order; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Text; 6 | 7 | namespace DoDSamples 8 | { 9 | [Orderer(SummaryOrderPolicy.SlowestToFastest, MethodOrderPolicy.Declared)] 10 | public class InstructionAndDataDependency 11 | { 12 | 13 | //[Benchmark] 14 | //public void InsDependency() 15 | //{ 16 | // InstructionLevelDependency.TestDependency(); 17 | //} 18 | 19 | //[Benchmark] 20 | //public void InsIndependency() 21 | //{ 22 | // InstructionLevelDependency.TestIndependency(); 23 | //} 24 | 25 | [Benchmark] 26 | public void InsIndependencySumUnroll() 27 | { 28 | InstructionLevelDependency.TestIndependencyUnrolledSum(); 29 | } 30 | 31 | [Benchmark] 32 | public void InsDependencySumUnroll() 33 | { 34 | InstructionLevelDependency.TestDependencyUnrolledSum(); 35 | } 36 | 37 | [Benchmark] 38 | public void InsDependencySum() 39 | { 40 | InstructionLevelDependency.TestSum(); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /DoDSamples/Samples/CacheSize.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace DoDSamples 6 | { 7 | public class CacheSize 8 | { 9 | // 10 | // This class will test the cache line sizes for various levels 11 | // The idea is simple: Move through the array loading a new cache line on every step 12 | // if we exceed the size of the array we start from the begining and continue. 13 | // We do this for a set amount of steps and mesure the assigment time, if we move to the 14 | // next cache level there will be a significant slowdown. 15 | // 16 | // How to Perform the test: 17 | // 18 | // int steps = 65536 * 1024; 19 | // int[] array = new int[1024 * 1024 * 1]; 20 | // 21 | // var e = Utils.Measure(() => c.TestK(steps, array)); 22 | // e = e* 1000; //Scale the time 23 | // Console.WriteLine((double) e / (double) steps); 24 | // 25 | public static void TestK(int steps, int[] array) 26 | { 27 | int lengthMod = array.Length - 1; 28 | 29 | for (int i = 0; i < steps; i++) 30 | { 31 | array[(i * 16) & lengthMod]++; 32 | } 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /DoDSamples/Samples/Utils.cs: -------------------------------------------------------------------------------- 1 | using BenchmarkDotNet.Jobs; 2 | using System; 3 | using System.Collections; 4 | using System.Collections.Generic; 5 | using System.Diagnostics; 6 | using System.Linq.Expressions; 7 | using System.Text; 8 | 9 | namespace DoDSamples 10 | { 11 | public static class Utils 12 | { 13 | public static long Measure(Action a) 14 | { 15 | // 16 | // Quick Wormup. 17 | // 18 | 19 | Console.WriteLine(" [1] WormUp ... "); 20 | 21 | for (int i = 0; i < 2; i++) 22 | { 23 | a(); 24 | } 25 | 26 | Console.WriteLine(" [2] Running ... "); 27 | 28 | Stopwatch w = new Stopwatch(); 29 | w.Start(); 30 | { 31 | a(); 32 | } 33 | w.Stop(); 34 | 35 | Console.Write($" [3] Took: {w.ElapsedMilliseconds}"); 36 | return w.ElapsedMilliseconds; 37 | } 38 | 39 | public static long MeasureSimple(Action a) 40 | { 41 | Stopwatch w = new Stopwatch(); 42 | w.Start(); 43 | { 44 | a(); 45 | } 46 | w.Stop(); 47 | 48 | return w.ElapsedMilliseconds; 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /DoDSamples/Samples/ArrayEnumerableByRef.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace DoDSamples 6 | { 7 | public readonly struct ArrayEnumerableByRef 8 | { 9 | private readonly T[] _target; 10 | 11 | public ArrayEnumerableByRef(T[] target) => _target = target; 12 | 13 | public Enumerator GetEnumerator() => new Enumerator(_target); 14 | 15 | public struct Enumerator 16 | { 17 | private readonly T[] _target; 18 | 19 | private int _index; 20 | 21 | public Enumerator(T[] target) 22 | { 23 | _target = target; 24 | _index = -1; 25 | } 26 | 27 | public readonly ref T Current 28 | { 29 | get 30 | { 31 | if (_target is null || _index < 0 || _index > _target.Length) 32 | { 33 | throw new InvalidOperationException(); 34 | } 35 | return ref _target[_index]; 36 | } 37 | } 38 | 39 | public bool MoveNext() => ++_index < _target.Length; 40 | 41 | public void Reset() => _index = -1; 42 | } 43 | } 44 | 45 | public static class ArrayExtensions 46 | { 47 | public static ArrayEnumerableByRef ToEnumerableByRef(this T[] array) => new ArrayEnumerableByRef(array); 48 | public static ArrayEnumerableByRef ToEnumerableByRef(this List list) => new ArrayEnumerableByRef(list.ToArray()); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /DoDSamples/Samples/Benchmarks/RefListvsList.cs: -------------------------------------------------------------------------------- 1 | using BenchmarkDotNet.Attributes; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace DoDSamples.Samples.Benchmarks 7 | { 8 | 9 | //public class RefListVSList 10 | //{ 11 | // private List list; 12 | // private RefList refList; 13 | // private const int size = 1_000_000; 14 | 15 | // [IterationSetup(Target = nameof(List))] 16 | // public void SetUpList() 17 | // { 18 | // list = new List(size); 19 | // for (int i = 0; i < size; i++) 20 | // { 21 | // list.Add(new POLine_v1() { ID = i }); 22 | // } 23 | // } 24 | 25 | // [IterationSetup(Target = nameof(RefList))] 26 | // public void SetUpRefList() 27 | // { 28 | // refList = new RefList(size); 29 | // for (int i = 0; i < size; i++) 30 | // { 31 | // refList.Add(new POLine_v1() { ID = i }); 32 | // } 33 | // } 34 | 35 | // [Benchmark] 36 | // public void List() 37 | // { 38 | // double sum = 0; 39 | 40 | // foreach(var item in list) 41 | // { 42 | // sum += item.Amount; 43 | // } 44 | // } 45 | 46 | // [Benchmark] 47 | // public void RefList() 48 | // { 49 | // double sum = 0; 50 | 51 | // foreach (var item in refList) 52 | // { 53 | // sum += item.Amount; 54 | // } 55 | // } 56 | //} 57 | } 58 | -------------------------------------------------------------------------------- /DoDSamples/Samples/POParser/OOPParser_Slow.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Text; 5 | using System.Text.RegularExpressions; 6 | 7 | namespace DoDSamples.Samples 8 | { 9 | public class POParser 10 | { 11 | private static Regex matchPOLine = 12 | new Regex( 13 | @"(?\d)\r\n(?[0-9]{4}-[0-9]{2}-[0-9]{2})T(?