第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問(wèn)題,去搜搜看,總會(huì)有你想問(wèn)的

為什么 Mono 運(yùn)行簡(jiǎn)單方法的速度較慢,而 RyuJIT 運(yùn)行速度明顯更快?

為什么 Mono 運(yùn)行簡(jiǎn)單方法的速度較慢,而 RyuJIT 運(yùn)行速度明顯更快?

C#
慕村225694 2021-11-14 15:06:16
出于好奇,我創(chuàng)建了一個(gè)簡(jiǎn)單的基準(zhǔn)測(cè)試,但無(wú)法解釋結(jié)果。作為基準(zhǔn)數(shù)據(jù),我準(zhǔn)備了一個(gè)帶有一些隨機(jī)值的結(jié)構(gòu)數(shù)組。準(zhǔn)備階段沒(méi)有進(jìn)行基準(zhǔn)測(cè)試:struct Val {    public float val;    public float min;    public float max;    public float padding;}const int iterations = 1000;Val[] values = new Val[iterations];// fill the array with randoms基本上,我想比較這兩個(gè)鉗位實(shí)現(xiàn):static class Clamps{    public static float ClampSimple(float val, float min, float max)    {        if (val < min) return min;                  if (val > max) return max;        return val;    }    public static T ClampExt<T>(this T val, T min, T max) where T : IComparable<T>    {        if (val.CompareTo(min) < 0) return min;        if (val.CompareTo(max) > 0) return max;        return val;    }}這是我的基準(zhǔn)方法:[Benchmark]public float Extension(){    float result = 0;    for (int i = 0; i < iterations; ++i)    {        ref Val v = ref values[i];        result += v.val.ClampExt(v.min, v.max);    }    return result;}[Benchmark]public float Direct(){    float result = 0;    for (int i = 0; i < iterations; ++i)    {        ref Val v = ref values[i];        result += Clamps.ClampSimple(v.val, v.min, v.max);    }    return result;}我將BenchmarkDotNet 0.10.12 版用于兩項(xiàng)工作:[MonoJob][RyuJitX64Job]這些是我得到的結(jié)果:BenchmarkDotNet=v0.10.12, OS=Windows 7 SP1 (6.1.7601.0)Intel Core i7-6920HQ CPU 2.90GHz (Skylake), 1 CPU, 8 logical cores and 4 physical coresFrequency=2836123 Hz, Resolution=352.5940 ns, Timer=TSC  [Host]    : .NET Framework 4.7 (CLR 4.0.30319.42000), 64bit RyuJIT-v4.7.3062.0  Mono      : Mono 5.12.0 (Visual Studio), 64bit  RyuJitX64 : .NET Framework 4.7 (CLR 4.0.30319.42000), 64bit RyuJIT-v4.7.3062.0我可以接受 Mono 在這里一般有點(diǎn)慢。但我不明白的是:為什么 Mono 運(yùn)行該Direct方法比記住使用非常簡(jiǎn)單的比較方法而使用具有附加方法調(diào)用的方法慢?ExtensionDirectExtensionRyuJIT 在這里展示了簡(jiǎn)單方法的 4 倍優(yōu)勢(shì)。誰(shuí)能解釋一下?
查看完整描述

1 回答

?
三國(guó)紛爭(zhēng)

TA貢獻(xiàn)1804條經(jīng)驗(yàn) 獲得超7個(gè)贊

由于沒(méi)有人想做一些拆卸的東西,我回答我自己的問(wèn)題。


原因似乎是 JIT 生成的本機(jī)代碼,而不是注釋中提到的數(shù)組邊界檢查或緩存問(wèn)題。


RyuJIT 為該ClampSimple方法生成了一個(gè)非常有效的代碼:


    vucomiss xmm1,xmm0

    jbe     M01_L00

    vmovaps xmm0,xmm1

    ret


M01_L00:

    vucomiss xmm0,xmm2

    jbe     M01_L01

    vmovaps xmm0,xmm2

    ret


M01_L01:

    ret

它使用 CPU 的本機(jī)ucomiss操作來(lái)比較floats,并使用快速movaps操作float在 CPU 的寄存器之間移動(dòng)這些s。


擴(kuò)展方法較慢,因?yàn)樗袔讉€(gè)對(duì) 的函數(shù)調(diào)用System.Single.CompareTo(System.Single),這是第一個(gè)分支:


lea     rcx,[rsp+30h]

vmovss  dword ptr [rsp+38h],xmm1

call    mscorlib_ni+0xda98f0

test    eax,eax

jge     M01_L00

vmovss  xmm0,dword ptr [rsp+38h]

add     rsp,28h

ret

讓我們看看 Mono 為該ClampSimple方法生成的本機(jī)代碼:


    cvtss2sd    xmm0,xmm0  

    movss       xmm1,dword ptr [rsp+8]  

    cvtss2sd    xmm1,xmm1  

    comisd      xmm1,xmm0  

    jbe         M01_L00  

    movss       xmm0,dword ptr [rsp+8]  

    cvtss2sd    xmm0,xmm0  

    cvtsd2ss    xmm0,xmm0  

    jmp         M01_L01 


M01_L00: 

    movss       xmm0,dword ptr [rsp]  

    cvtss2sd    xmm0,xmm0  

    movss       xmm1,dword ptr [rsp+10h]  

    cvtss2sd    xmm1,xmm1  

    comisd      xmm1,xmm0  

    jp          M01_L02

    jae         M01_L02  

    movss       xmm0,dword ptr [rsp+10h]  

    cvtss2sd    xmm0,xmm0  

    cvtsd2ss    xmm0,xmm0  

    jmp         M01_L01


M01_L02:

    movss       xmm0,dword ptr [rsp]  

    cvtss2sd    xmm0,xmm0  

    cvtsd2ss    xmm0,xmm0  


M01_L01:

    add         rsp,18h  

    ret 

Mono 的代碼轉(zhuǎn)換floats為doubles 并使用comisd. 此外,在準(zhǔn)備返回值時(shí),還有奇怪的“轉(zhuǎn)換翻轉(zhuǎn)” float? double? float。而且在內(nèi)存和寄存器之間還有更多的移動(dòng)。這解釋了為什么 Mono 的簡(jiǎn)單方法代碼比 RyuJIT 的代碼慢。


該Extension方法代碼與 RyuJIT 的代碼非常相似,但再次具有奇怪的轉(zhuǎn)換翻轉(zhuǎn)float? double? float:


movss       xmm0,dword ptr [rbp-10h]  

cvtss2sd    xmm0,xmm0  

movsd       xmm1,xmm0  

cvtsd2ss    xmm1,xmm1  

lea         rbp,[rbp]  

mov         r11,2061520h  

call        r11  

test        eax,eax  

jge         M0_L0 

movss       xmm0,dword ptr [rbp-10h]  

cvtss2sd    xmm0,xmm0  

cvtsd2ss    xmm0,xmm0

ret

似乎 RyuJIT 可以生成更高效的代碼來(lái)處理floats。Mono 將floats 視為doubles 并每次轉(zhuǎn)換值,這也會(huì)導(dǎo)致 CPU 寄存器和內(nèi)存之間的額外值傳輸。


請(qǐng)注意,所有這些僅對(duì) Windows x64 有效。我不知道這個(gè)基準(zhǔn)測(cè)試在 Linux 或 Mac 上的表現(xiàn)如何。


查看完整回答
反對(duì) 回復(fù) 2021-11-14
  • 1 回答
  • 0 關(guān)注
  • 353 瀏覽

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)