亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

詳解Java編譯優(yōu)化之循環(huán)展開(kāi)和粗化鎖

 更新時(shí)間:2021年06月02日 14:14:54   作者:flydean  
之前在講JIT的時(shí)候,有提到在編譯過(guò)程中的兩種優(yōu)化循環(huán)展開(kāi)和粗化鎖,今天從Assembly的角度來(lái)驗(yàn)證一下這兩種編譯優(yōu)化方法,快來(lái)看看吧。

循環(huán)展開(kāi)和粗化鎖

我們先來(lái)回顧一下什么是循環(huán)展開(kāi)。

循環(huán)展開(kāi)就是說(shuō),像下面的循環(huán)遍歷的例子:

for (int i = 0; i < 1000; i++) {
    x += 0x51;
}

因?yàn)槊看窝h(huán)都需要做跳轉(zhuǎn)操作,所以為了提升效率,上面的代碼其實(shí)可以被優(yōu)化為下面的:

for (int i = 0; i < 250; i++) {
    x += 0x144; //0x51 * 4
}

注意上面我們使用的是16進(jìn)制數(shù)字,至于為什么要使用16進(jìn)制呢?這是為了方便我們?cè)诤竺娴腶ssembly代碼中快速找到他們。

好了,我們?cè)僭?x += 0x51 的外面加一層synchronized鎖,看一下synchronized鎖會(huì)不會(huì)隨著loop unrolling展開(kāi)的同時(shí)被粗化。

for (int i = 0; i < 1000; i++) {
    synchronized (this) {
        x += 0x51;
    }
}

萬(wàn)事具備,只欠我們的運(yùn)行代碼了,這里我們還是使用JMH來(lái)執(zhí)行。

相關(guān)代碼如下:

@Warmup(iterations = 10, time = 1, timeUnit = TimeUnit.SECONDS)
@Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
@Fork(value = 1,
        jvmArgsPrepend = {
        "-XX:-UseBiasedLocking",
                "-XX:CompileCommand=print,com.flydean.LockOptimization::test"
}
        )
@State(Scope.Benchmark)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public class LockOptimization {

    int x;
    @Benchmark
    @CompilerControl(CompilerControl.Mode.DONT_INLINE)
    public void test() {
        for (int i = 0; i < 1000; i++) {
            synchronized (this) {
                x += 0x51;
            }
        }
    }

    public static void main(String[] args) throws RunnerException {
        Options opt = new OptionsBuilder()
                .include(LockOptimization.class.getSimpleName())
                .build();
        new Runner(opt).run();
    }
}

上面的代碼中,我們?nèi)∠似蜴i的使用:-XX:-UseBiasedLocking。為啥要取消這個(gè)選項(xiàng)呢?因?yàn)槿绻谄蜴i的情況下,如果線程獲得鎖之后,在之后的執(zhí)行過(guò)程中,如果沒(méi)有其他的線程訪問(wèn)該鎖,那么持有偏向鎖的線程則不需要觸發(fā)同步。

為了更好的理解synchronized的流程,這里我們將偏向鎖禁用。

其他的都是我們之前講過(guò)的JMH的常規(guī)操作。

接下來(lái)就是見(jiàn)證奇跡的時(shí)刻了。

分析Assembly日志

我們運(yùn)行上面的程序,將會(huì)得到一系列的輸出。因?yàn)楸疚牟⒉皇侵v解Assembly語(yǔ)言的,所以本文只是大概的理解一下Assembly的使用,并不會(huì)詳細(xì)的進(jìn)行Assembly語(yǔ)言的介紹,如果有想深入了解Assembly的朋友,可以在文后留言。

分析Assembly的輸出結(jié)果,我們可以看到結(jié)果分為C1-compiled nmethod和C2-compiled nmethod兩部分。

先看C1-compiled nmethod:

第一行是monitorenter,表示進(jìn)入鎖的范圍,后面還跟著對(duì)于的代碼行數(shù)。

最后一行是monitorexit,表示退出鎖的范圍。

中間有個(gè)add $0x51,%eax操作,對(duì)于著我們的代碼中的add操作。

可以看到C1—compiled nmethod中是沒(méi)有進(jìn)行Loop unrolling的。

我們?cè)倏纯碈2-compiled nmethod:

和C1很類似,不同的是add的值變成了0x144,說(shuō)明進(jìn)行了Loop unrolling,同時(shí)對(duì)應(yīng)的鎖范圍也跟著進(jìn)行了擴(kuò)展。

最后看下運(yùn)行結(jié)果:

Benchmark              Mode  Cnt     Score     Error  Units

LockOptimization.test  avgt    5  5601.819 ± 620.017  ns/op

得分還不錯(cuò)。

禁止Loop unrolling

接下來(lái)我們看下如果將Loop unrolling禁掉,會(huì)得到什么樣的結(jié)果。

要禁止Loop unrolling,只需要設(shè)置-XX:LoopUnrollLimit=1即可。

我們?cè)龠\(yùn)行一下上面的程序:

可以看到C2-compiled nmethod中的數(shù)字變成了原本的0x51,說(shuō)明并沒(méi)有進(jìn)行Loop unrolling。

再看看運(yùn)行結(jié)果:

Benchmark              Mode  Cnt      Score      Error  Units

LockOptimization.test  avgt    5  20846.709 ± 3292.522  ns/op

可以看到運(yùn)行時(shí)間基本是優(yōu)化過(guò)后的4倍左右。說(shuō)明Loop unrolling還是非常有用的。

以上就是詳解Java編譯優(yōu)化之循環(huán)展開(kāi)和粗化鎖的詳細(xì)內(nèi)容,更多關(guān)于Java編譯優(yōu)化之循環(huán)展開(kāi)和粗化鎖的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 淺談Java的LinkedHashSet源碼

    淺談Java的LinkedHashSet源碼

    這篇文章主要介紹了淺談Java的LinkedHashSet源碼,底層是鏈表實(shí)現(xiàn)的,是set集合中唯一一個(gè)能保證怎么存就怎么取的集合對(duì)象
    因?yàn)槭荋ashSet的子類,所以也是保證元素唯一的,與HashSet的原理一樣,需要的朋友可以參考下
    2023-09-09
  • Java Math.round函數(shù)詳解

    Java Math.round函數(shù)詳解

    這篇文章主要介紹了Java Math.round函數(shù)詳解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • Java爬取網(wǎng)站源代碼和鏈接代碼實(shí)例

    Java爬取網(wǎng)站源代碼和鏈接代碼實(shí)例

    這篇文章主要介紹了Java爬取網(wǎng)站源代碼和鏈接代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-11-11
  • Mybatis動(dòng)態(tài)sql超詳細(xì)講解

    Mybatis動(dòng)態(tài)sql超詳細(xì)講解

    動(dòng)態(tài)SQL是MyBatis的強(qiáng)大特性之一,顧名思義就是會(huì)動(dòng)的SQL,即是能夠靈活的根據(jù)某種條件拼接出完整的SQL語(yǔ)句,下面這篇文章主要給大家介紹了關(guān)于Mybatis動(dòng)態(tài)sql的相關(guān)資料,需要的朋友可以參考下
    2023-04-04
  • 五個(gè)很實(shí)用的IDEA使用技巧分享

    五個(gè)很實(shí)用的IDEA使用技巧分享

    IntelliJ IDEA 是一款優(yōu)秀的 Java 集成開(kāi)發(fā)環(huán)境,它提供了許多強(qiáng)大的功能和快捷鍵,可以幫助開(kāi)發(fā)者提高編碼效率和質(zhì)量,本文就在為你介紹博主常用的五個(gè)IntelliJ IDEA使用技巧,希望能夠給你帶來(lái)一些工作效率上的提升
    2023-10-10
  • Java8 HashMap擴(kuò)容算法實(shí)例解析

    Java8 HashMap擴(kuò)容算法實(shí)例解析

    這篇文章主要介紹了Java8 HashMap擴(kuò)容算法實(shí)例解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-12-12
  • Java實(shí)現(xiàn)四則混合運(yùn)算代碼示例

    Java實(shí)現(xiàn)四則混合運(yùn)算代碼示例

    這篇文章主要介紹了Java實(shí)現(xiàn)四則混合運(yùn)算代碼示例,文中展示了詳細(xì)代碼,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-10-10
  • 實(shí)例講解Java的Spring框架中的AOP實(shí)現(xiàn)

    實(shí)例講解Java的Spring框架中的AOP實(shí)現(xiàn)

    這篇文章主要介紹了Java的Spring框架中的AOP實(shí)現(xiàn)實(shí)例,AOP面向切面編程其實(shí)也可以被看作是一個(gè)設(shè)計(jì)模式去規(guī)范項(xiàng)目的結(jié)構(gòu),需要的朋友可以參考下
    2016-04-04
  • commons io文件操作示例分享

    commons io文件操作示例分享

    這篇文章主要介紹了commons io文件操作示例分享,需要的朋友可以參考下
    2014-02-02
  • SpringBoot+Mybatis使用Enum枚舉類型總是報(bào)錯(cuò)No enum constant XX問(wèn)題

    SpringBoot+Mybatis使用Enum枚舉類型總是報(bào)錯(cuò)No enum constant&n

    這篇文章主要介紹了SpringBoot+Mybatis使用Enum枚舉類型總是報(bào)錯(cuò)No enum constant XX問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-12-12

最新評(píng)論