There are several implementations of MD5 , for example. Finding out which method is faster is not a problem. How to correctly find out which of these methods gives a heavy load on the processor?
- onemd5 does all the operations exclusively on the processor, therefore, the fact that it takes longer to execute and loads the processor more. rather, any of these methods are guaranteed to load the kernel 100% just for different times - Mike
- @Mike, i.e. it turns out, what takes longer CPU time - and that gives a greater load on the processor? - User101057
- @Mike obvious. If you need performance reports, just use any profiler. For example jetbrains.com/profiler - Artem Okonechnikov
- @ArtyomOkonechnikov, well, use third-party profilers in such a simple matter, besides not budget ones - too much. - User101057
- one@ User101057 The load on the processor is in principle measured in the time of its useful work (when it is not transferred to the shutdown state by the operating system due to lack of work). on the other hand, it is possible to measure only the operating time only if the system is no longer busy at this time, because if there are more than cores wishing to receive the processor, then the OS will divide the time in portions between them - Mike
1 answer
To get the CPU time spent on the single-threaded method, subtract the values ββof ProcessThread.TotalProcessorTime after and before the method is executed. Accordingly, the processor load (average) created during its execution can be found by dividing the obtained value by Environment.ProcessorCount * ΠΡΠ΅ΠΌΡΠΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ . To improve the accuracy of calculations, make a measurement several times and find the average Example:
using System; using System.Collections.Generic; using System.Data; using System.Text; using System.Diagnostics; using System.Threading; namespace ConsoleTest1 { class Program { /* ΠΠ·ΠΌΠ΅ΡΡΠ΅ΠΌΡΠΉ ΠΌΠ΅ΡΠΎΠ΄ */ public static Int64 DoSomething(Int64 x) { Int64 res = 1; for (Int64 i = 1; i <= x; i++) res += i; return res; } [System.Runtime.InteropServices.DllImport("kernel32.dll")] static extern uint GetCurrentThreadId(); const int N = 50; //ΡΠΈΡΠ»ΠΎ ΠΈΡΠ΅ΡΠ°ΡΠΈΠΉ static void Main(string[] args) { Console.WriteLine(DoSomething(5000000).ToString()); //ΠΏΡΠΎΠ³ΡΠ΅Π² Int64 sum=0; Stopwatch sw = new Stopwatch(); var id = GetCurrentThreadId();//ΠΏΠΎΠ»ΡΡΠ°Π΅ΠΌ ID ΡΠ΅ΠΊΡΡΠ΅Π³ΠΎ ΠΏΠΎΡΠΎΠΊΠ° Process pr = Process.GetCurrentProcess(); ProcessThread thread = null; //Π½Π°Ρ
ΠΎΠ΄ΠΈΠΌ ΠΎΠ±ΡΠ΅ΠΊΡ ProcessThread Π΄Π»Ρ ΡΠ΅ΠΊΡΡΠ΅Π³ΠΎ ΠΏΠΎΡΠΎΠΊΠ° foreach (ProcessThread th in pr.Threads) { if (th.Id == (int)id) thread = th; } if (thread == null) { Console.WriteLine("ProcessThread not found"); return; } sw.Start();//Π½Π°ΡΠ°Π»ΠΎ ΠΈΠ·ΠΌΠ΅ΡΠ΅Π½ΠΈΠΉ var before = thread.TotalProcessorTime.Ticks; for (int i = 0; i < N; i++) { sum += DoSomething(50000000);//Π²ΡΠ·ΠΎΠ² ΠΈΠ·ΠΌΠ΅ΡΡΠΌΠΎΠ³ΠΎ ΠΌΠ΅ΡΠΎΠ΄Π° } Console.WriteLine(sum.ToString()); var after = thread.TotalProcessorTime.Ticks; sw.Stop();//ΠΊΠΎΠ½Π΅Ρ ΠΈΠ·ΠΌΠ΅ΡΠ΅Π½ΠΈΠΉ double processor_time = TimeSpan.FromTicks(after - before).TotalMilliseconds / N; double total_time = (sw.ElapsedMilliseconds) / (double)N; double usage = (processor_time) / (Environment.ProcessorCount * total_time) * 100.0; Console.WriteLine("Processor time:" + Math.Round(processor_time,2).ToString()); Console.WriteLine("Total time:" + total_time.ToString()); Console.WriteLine("Usage %:" + Math.Round(usage,1).ToString()); } } } If DoSomething performs only bare calculations, without referring to I / O or waiting for events, the load value will be close to 100% / Environment.ProcessorCount . If it contains a Thread.Sleep call, the load will be close to zero. Everything else is in the middle.
If the method is multi-threaded, you must either summarize over all the threads involved, or simply take a Process.TotalProcessorTime for a rough approximation (assuming that nothing else is happening in the process at the moment).
- But it will not be easier, instead of cycling, to take BenchmarkDotNet, and compare the two methods? - Primus Singularis