আমি এখানে প্রাচীরের বিরুদ্ধে মাথা ঠাট্টা করছি, তাই আমি আশা করি আপনারা কেউ কেউ আমাকে শিক্ষিত করতে সক্ষম হবেন। আমি বেঞ্চমার্কডটনেট ব্যবহার করে কিছু পারফরম্যান্স বেঞ্চমার্ক করছিলাম এবং আমি এই অদ্ভুত মামলার দিকে ছুঁড়েছি যেখানে মনে হয় যে কোনও সদস্য ঘোষণা করা const
পারফরম্যান্সকে যথেষ্ট হ্রাস করে।
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
using System;
namespace PerfTest
{
[DisassemblyDiagnoser(printAsm: true, printSource: true)]
public class Test
{
private int[] data;
private int Threshold = 90;
private const int ConstThreshold = 90;
[GlobalSetup]
public void GlobalSetup()
{
data = new int[1000];
var random = new Random(42);
for (var i = 0; i < data.Length; i++)
{
data[i] = random.Next(100);
}
}
static void Main(string[] args)
{
var summary = BenchmarkRunner.Run<Test>();
}
[Benchmark(Baseline = true)]
public void ClampToMemberValue()
{
for (var i = 0; i < data.Length; i++)
{
if (data[i] > Threshold) data[i] = Threshold;
}
}
[Benchmark]
public void ClampToConstValue()
{
for (var i = 0; i < data.Length; i++)
{
if (data[i] > ConstThreshold) data[i] = ConstThreshold;
}
}
}
}
লক্ষ্য করুন যে দুটি পরীক্ষার পদ্ধতির মধ্যে একমাত্র পার্থক্য হ'ল তারা কোনও নিয়মিত সদস্যের পরিবর্তনশীল বা কনস্টের সদস্যের সাথে তুলনা করে।
বেঞ্চমার্কডটনেটের মতে কনস্ট মানটি ব্যবহার করা উল্লেখযোগ্যভাবে ধীর এবং কেন তা আমি বুঝতে পারি না।
BenchmarkDotNet=v0.11.5, OS=Windows 10.0.18362
Intel Core i7-5820K CPU 3.30GHz (Broadwell), 1 CPU, 12 logical and 6 physical cores
.NET Core SDK=3.0.100
[Host] : .NET Core 3.0.0 (CoreCLR 4.700.19.46205, CoreFX 4.700.19.46214), 64bit RyuJIT
DefaultJob : .NET Core 3.0.0 (CoreCLR 4.700.19.46205, CoreFX 4.700.19.46214), 64bit RyuJIT
| Method | Mean | Error | StdDev | Ratio |
|------------------- |---------:|---------:|---------:|------:|
| ClampToMemberValue | 590.4 ns | 1.980 ns | 1.852 ns | 1.00 |
| ClampToConstValue | 724.6 ns | 4.184 ns | 3.709 ns | 1.23 |
জেআইটি সংকলিত কোডটির দিকে তাকানো এটি যতদূর আমি বলতে পারি তা ব্যাখ্যা করে না। দুটি পদ্ধতির কোড এখানে। পার্থক্যটি কেবলমাত্র কোনও রেজিস্টার বা আক্ষরিকের তুলনায় করা হয় কিনা।
00007ff9`7f1b8500 PerfTest.Test.ClampToMemberValue()
for (var i = 0; i < data.Length; i++)
^^^^^^^^^
00007ff9`7f1b8504 33c0 xor eax,eax
for (var i = 0; i < data.Length; i++)
^^^^^^^^^^^^^^^
00007ff9`7f1b8506 488b5108 mov rdx,qword ptr [rcx+8]
00007ff9`7f1b850a 837a0800 cmp dword ptr [rdx+8],0
00007ff9`7f1b850e 7e2e jle 00007ff9`7f1b853e
00007ff9`7f1b8510 8b4910 mov ecx,dword ptr [rcx+10h]
if (data[i] > Threshold) data[i] = Threshold;
^^^^^^^^^^^^^^^^^^^^^^^^
00007ff9`7f1b8513 4c8bc2 mov r8,rdx
00007ff9`7f1b8516 458b4808 mov r9d,dword ptr [r8+8]
00007ff9`7f1b851a 413bc1 cmp eax,r9d
00007ff9`7f1b851d 7324 jae 00007ff9`7f1b8543
00007ff9`7f1b851f 4c63c8 movsxd r9,eax
00007ff9`7f1b8522 43394c8810 cmp dword ptr [r8+r9*4+10h],ecx
00007ff9`7f1b8527 7e0e jle 00007ff9`7f1b8537
if (data[i] > Threshold) data[i] = Threshold;
^^^^^^^^^^^^^^^^^^^^
00007ff9`7f1b8529 4c8bc2 mov r8,rdx
00007ff9`7f1b852c 448bc9 mov r9d,ecx
00007ff9`7f1b852f 4c63d0 movsxd r10,eax
00007ff9`7f1b8532 47894c9010 mov dword ptr [r8+r10*4+10h],r9d
for (var i = 0; i < data.Length; i++)
^^^
00007ff9`7f1b8537 ffc0 inc eax
00007ff9`7f1b8539 394208 cmp dword ptr [rdx+8],eax
00007ff9`7f1b853c 7fd5 jg 00007ff9`7f1b8513
}
^
00007ff9`7f1b853e 4883c428 add rsp,28h
এবং
00007ff9`7f1a8500 PerfTest.Test.ClampToConstValue()
for (var i = 0; i < data.Length; i++)
^^^^^^^^^
00007ff9`7f1a8504 33c0 xor eax,eax
for (var i = 0; i < data.Length; i++)
^^^^^^^^^^^^^^^
00007ff9`7f1a8506 488b5108 mov rdx,qword ptr [rcx+8]
00007ff9`7f1a850a 837a0800 cmp dword ptr [rdx+8],0
00007ff9`7f1a850e 7e2d jle 00007ff9`7f1a853d
if (data[i] > ConstThreshold) data[i] = ConstThreshold;
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
00007ff9`7f1a8510 488bca mov rcx,rdx
00007ff9`7f1a8513 448b4108 mov r8d,dword ptr [rcx+8]
00007ff9`7f1a8517 413bc0 cmp eax,r8d
00007ff9`7f1a851a 7326 jae 00007ff9`7f1a8542
00007ff9`7f1a851c 4c63c0 movsxd r8,eax
00007ff9`7f1a851f 42837c81105a cmp dword ptr [rcx+r8*4+10h],5Ah
00007ff9`7f1a8525 7e0f jle 00007ff9`7f1a8536
if (data[i] > ConstThreshold) data[i] = ConstThreshold;
^^^^^^^^^^^^^^^^^^^^^^^^^
00007ff9`7f1a8527 488bca mov rcx,rdx
00007ff9`7f1a852a 4c63c0 movsxd r8,eax
00007ff9`7f1a852d 42c74481105a000000 mov dword ptr [rcx+r8*4+10h],5Ah
for (var i = 0; i < data.Length; i++)
^^^
00007ff9`7f1a8536 ffc0 inc eax
00007ff9`7f1a8538 394208 cmp dword ptr [rdx+8],eax
00007ff9`7f1a853b 7fd3 jg 00007ff9`7f1a8510
}
^
00007ff9`7f1a853d 4883c428 add rsp,28h
আমি নিশ্চিত যে আমি কিছু উপেক্ষা করেছি এমন কিছু আছে তবে আমি এই মুহুর্তে এটি আঁকতে পারি না তাই আমি কী ব্যাখ্যা করতে পারি তার জন্য ইনপুট খুঁজছি।
cmp
এবং mov
নির্দেশাবলী যা const পথ জন্য ব্যবহার করা হয় একটি রেজিস্টার ভিত্তিক নির্দেশাবলীর চেয়ে আরো মেমরি দখল করে কারণ একটি সংখ্যা এনকোডিং অতিরিক্ত বাইট এবং মোট নিতে আরও CPU- র চক্র চালানো (9 বাইট বনাম 5 বাইট প্রয়োজন mov
এবং 6 বাইট বনাম CMP 5 বাইটস) । এবং mov ecx,dword ptr [rcx+10h]
নন-কনস্ট্যান্ট সংস্করণে অতিরিক্ত নির্দেশনা থাকা সত্ত্বেও এটি সম্ভবত জেআইটি সংকলক রিলিজ সংস্করণে লুপের বাইরে থাকতে অনুকূলিত করেছে।