diff --git a/Lab3/Analysis.xlsx b/Lab3/Analysis.xlsx new file mode 100644 index 0000000..9d96d18 Binary files /dev/null and b/Lab3/Analysis.xlsx differ diff --git a/Lab3/Ataskaita.docx b/Lab3/Ataskaita.docx new file mode 100644 index 0000000..ae5a57e Binary files /dev/null and b/Lab3/Ataskaita.docx differ diff --git a/Lab3/Program.cs b/Lab3/Program.cs index afac41d..1b2dd0f 100644 --- a/Lab3/Program.cs +++ b/Lab3/Program.cs @@ -1,4 +1,6 @@ -using System.Reflection.Metadata.Ecma335; +using System.Diagnostics; +using System.Reflection.Metadata.Ecma335; +using System.Runtime.InteropServices; namespace Lab3 { @@ -36,11 +38,69 @@ namespace Lab3 return k; } - public static long methodToAnalysis2(int n, int[] arr) + public static long methodToAnalysisParallel1(int[] arr) + { + int coreCount = Environment.ProcessorCount; + + int n = arr.Length; + if (n % coreCount != 0) + { + throw new Exception("Array size is not divisable by the core count"); + } + + long nPerCore = n / coreCount; + long nnPerCore = n * n / coreCount; + + var tasks = new List>(); + for (int coreIdx = 0; coreIdx < coreCount; coreIdx++) + { + int localCoreIdx = coreIdx; + var task = Task.Factory.StartNew(() => + { + long subk = 0; + for (long i = 0; i < nPerCore; i++) + { + if (arr[localCoreIdx * nPerCore + i] / 7 == 0) + { + subk -= 2; + } + else + { + subk += 3; + } + } + + if (arr[0] > 0) + { + for (long i = 0; i < nnPerCore; i++) + { + if (arr[0] > 0) + { + subk += 3; + } + } + } + + return subk; + }); + tasks.Add(task); + } + + long k = n; + Task.WaitAll(tasks.ToArray()); + foreach (var task in tasks) + { + k += task.Result; + } + + return k; + } + + public static long methodToAnalysis2(int[] arr) { long k = 0; - for (int i = 0; i < n; i++) + for (int i = 0; i < arr.Length; i++) { k += arr[i] + FF4(i, arr); } @@ -48,6 +108,43 @@ namespace Lab3 return k; } + public static long methodToAnalysisParallel2(int[] arr) + { + int coreCount = Environment.ProcessorCount; + + int n = arr.Length; + if (n % coreCount != 0) + { + throw new Exception("Array size is not divisable by the core count"); + } + + var tasks = new List>(); + for (int coreIdx = 0; coreIdx < coreCount; coreIdx++) + { + int localCoreIdx = coreIdx; + var task = Task.Factory.StartNew(() => + { + long subk = 0; + for (int i = 0; i < n / coreCount; i++) + { + int j = localCoreIdx * (n / coreCount) + i; + subk += arr[j] + FF4(j, arr); + } + return subk; + }); + tasks.Add(task); + } + + long k = 0; + Task.WaitAll(tasks.ToArray()); + foreach (var task in tasks) + { + k += task.Result; + } + + return k; + } + public static long FF4(int n, int[] arr) { if (n > 0 && arr.Length > n && arr[n] < 0) @@ -95,14 +192,104 @@ namespace Lab3 return memo[n, weightLimit]; } + public static int[] createTestArray(int n) + { + int[] arr = new int[n]; + for (int i = 0; i < n; i++) + { + arr[i] = -(i+1); + } + return arr; + } + + public static void benchmarkKnapsack(Func knapsackFunc, int[] sizes, bool silent = false) + { + var stopWatch = new Stopwatch(); + foreach (int size in sizes) + { + int weightLimit = size*10; + int[] weights = createTestArray(size); + int[] values = createTestArray(size); + int n = weights.Length; + + if (silent) { + knapsackFunc(weightLimit, n, weights, values); + } else { + stopWatch.Reset(); + stopWatch.Start(); + knapsackFunc(weightLimit, n, weights, values); + stopWatch.Stop(); + Console.WriteLine("{0}, {1}", size, Math.Round(stopWatch.Elapsed.TotalSeconds * 1000, 5)); + } + } + } + + public static void benchmarkSimple(Func func, int[] sizes, bool silent = false) + { + var stopWatch = new Stopwatch(); + foreach (int size in sizes) + { + int[] arr = createTestArray(size); + + if (silent) + { + func(arr); + } + else + { + stopWatch.Reset(); + stopWatch.Start(); + func(arr); + stopWatch.Stop(); + Console.WriteLine("{0}, {1}", size, Math.Round(stopWatch.Elapsed.TotalSeconds * 1000, 5)); + } + } + } + static void Main(string[] args) { - int weightLimit = 15; - int[] weights = new int[]{ 7, 2, 1, 9 }; - int[] values = new int[]{ 5, 4, 7, 2 }; - int n = weights.Length; - Console.WriteLine(knapsackDP(weightLimit, n, weights, values)); - Console.WriteLine(knapsack(weightLimit, n, weights, values)); + int cores = Environment.ProcessorCount; + Console.WriteLine("The number of processors on this computer is {0}", Environment.ProcessorCount); + + /* + Console.WriteLine(); + + int[] knapsackSizes = new int[] { 20, 21, 22, 23, 24, 25, 26, 27, 28 }; + Console.WriteLine("Knapsack Recursive (ms):"); + benchmarkKnapsack(knapsack, new int[] { 10 }, true); + benchmarkKnapsack(knapsack, knapsackSizes); + Console.WriteLine("Knapsack DP (ms):"); + benchmarkKnapsack(knapsackDP, new int[] { 10 }, true); + benchmarkKnapsack(knapsackDP, knapsackSizes); + */ + + /* + Console.WriteLine(); + + int[] method1Sizes = new int[] { 10, 50, 100, 250, 500, 1000, 2000 } + .Select(size => size * cores) + .ToArray(); + Console.WriteLine("methodToAnalysis1 (ms):"); + benchmarkSimple(methodToAnalysis1, new int[] { cores }, true); + benchmarkSimple(methodToAnalysis1, method1Sizes); + Console.WriteLine("methodToAnalysisParallel1 (ms):"); + benchmarkSimple(methodToAnalysisParallel1, new int[] { cores }, true); + benchmarkSimple(methodToAnalysisParallel1, method1Sizes); + */ + + + Console.WriteLine(); + + int[] method2Sizes = new int[] { 10, 50, 100, 500, 1000, 3500 } + .Select(size => size * cores) + .ToArray(); + Console.WriteLine("methodToAnalysis2 (ms):"); + benchmarkSimple(methodToAnalysis2, new int[] { cores }, true); + benchmarkSimple(methodToAnalysis2, method2Sizes); + Console.WriteLine("methodToAnalysisParallel2 (ms):"); + benchmarkSimple(methodToAnalysisParallel2, new int[] { cores }, true); + benchmarkSimple(methodToAnalysisParallel2, method2Sizes); + } } } \ No newline at end of file