• <noscript id="e0iig"><kbd id="e0iig"></kbd></noscript>
  • <td id="e0iig"></td>
  • <option id="e0iig"></option>
  • <noscript id="e0iig"><source id="e0iig"></source></noscript>
  • 學習筆記(1):編譯的基本概念

    什么是編譯

    對于語言,有高級語言,低級語言和機器語言的方式來表示,因為機器是只能做數字計算的,能夠讓機器去運算的只有機器語言,從高級語言轉為機器語言的過程就叫做編譯,由編譯器來完成
    例如:由 C 轉換為匯編語言需要 匯編器來執行
    C 和匯編語言轉換為機器語言都是由編譯器來指向的

    編譯器的架構

    傳統的編譯器架構
    傳統的編譯器架構
    前端:詞法分析,語法分析,語義分析,生成中間代碼

    優化器:中間代碼優化

    后端:生成機器碼

    編譯優化的方法

    常量傳播
    編譯優化時,能夠將計算出來的變量直接替換為常量

    void main()
    {
    	int a=1;
    	printf("%d",a);
    }
    

    優化后

    void main()
    {
    	printf("%d",1);
    }
    

    公共子表達式消除
    如果一個表達式已經計算過,并且表達式中的變量一直沒有變化,那么這個這個表達式就是公共子表達式

    void main()
    {
    	int a =1,b=2,x=0;
    	x=(a+c)*12+(c+a);
    }
    

    優化后

    void main()
    {
    	int a =1,b=2,x=0;
    	x=E*12+E;
    }
    

    方法內聯

    循環優化

    循環嵌套外大內小

    循環條件使用<要快于<=
    for(int i=0;i<50;i++)

    把外層可以計算的盡可能放到外層,減少在內層的運算,有判斷條件的語句和與循環不相關的操作語句盡量放在for外面

    循環展開

    循環交換
    https://blog.csdn.net/zhengzhoudaxue2/article/details/6459890

    再看這個例子

    int main(int argc,char **argv)
    {
     	int i,m,k1,k2,k3,k4,k5,k6,k7,k8;
     	m=10000000;
    
     	for(i=0;i<m;i++){
      		k1++;  k5++;
      		k2++;  k6++;
      		k3++;  k7++;
      		k4++;  k8++;
     }
     return (0);
    }
    

    這個for循環,我們是讓這些數每次循環都加1,這個效率也不是達到了最優,是這樣的,在每次for循環的時候,編譯器會給變量i,變量m每個獨占一個寄存器,因為是循環嘛,編譯器給i和m也是為了效率考慮,不用再向寄存器加載每次循環的判斷變量了,但是,一般基于Intel的處理器都只有8個通用寄存器,這樣,我們就剩下了6個寄存器給for循環里的內容中的變量使用,但是,我們的變量有8個,我們這時會在把其他的變量入棧,這樣,我們的效率變低了,每次出戰或者入棧都會消耗兩個CPU時鐘周期

    優化后:

    int main(int argc,char **argv)
    {
    	 int i,m,k1,k2,k3,k4,k5,k6,k7,k8;
     	 m=10000000;
     
     	for(i=0;i<m;i++){
      		k1++;  k5++;
      		k2++;  k6++;
     }
    	 for(i=0;i<m;i++){
      		k3++;  k7++;
      		k4++;  k8++;
     }
     return (0)
    }
    

    LLVM

    llvm項目是模塊化、可重用的編譯器以及工具鏈技術的集合

    LLVM架構
    LLVM架構

    • 不同的前端后端使用統一的中間代碼LLVM Intermediate Representation(LLVM IR)
    • 如果需要支持一種新的編程語言,那么只需要實現一個新的前端
    • 如果需要支持一種新的硬件設備,那么只需要實現一個新的后端
    • 優化階段是一個通用的階段,它針對的是統一的LLVM IR,不論是支持新的編程語言還是支持新的硬件設備,都不需要對優化階段做修改
    • 相比之下,GCC的前端和后端沒分得太開,前端后端耦合在了一起。所以GCC為了支持一門新的語言,或者為了支持一個新的目標平臺,就 變得特別困難
    • LLVM現在被作為實現各種靜態和運行時編譯語言的通用基礎結構(GCC家族、Java、.NET、Python、Ruby、Scheme、Haskell、D等)

    Clang

    Clang是LLVM的一個子項目,基于LLVM架構的C/C++/Objective-C編譯器的前端

    Clang對比GCC的優點

    • 編譯速度快:在某些平臺上,Clang的編譯速度顯著的快過GCC(Debug模式下編譯OC速度比GGC快3倍)
    • 占用內存小:Clang生成的AST所占用的內存是GCC的五分之一左右
    • 模塊化設計:Clang采用基于庫的模塊化設計,易于 IDE 集成及其他用途的重用
    • 診斷信息可讀性強:在編譯過程中,Clang 創建并保留了大量詳細的元數據 (metadata),有利于調試和錯誤報告
    • 設計清晰簡單,容易理解,易于擴展增強

    Clang和LLVM
    LLVM整體架構,前端用的是clang,廣義的LLVM是指整個LLVM架構,一般狹義的LLVM指的是LLVM后端(包含代碼優化和目標代碼生成)。

    源代碼(c/c++)經過clang–> 中間代碼(經過一系列的優化,優化用的是Pass) --> 機器碼

    參考

    深入淺出讓你理解什么是LLVM
    https://www.jianshu.com/p/1367dad95445
    編譯器常用優化方法
    https://www.jianshu.com/p/0caa9cfd995a
    你的for循環真的高效嗎
    https://blog.csdn.net/zhengzhoudaxue2/article/details/6453366

    版權聲明:本文為weixin_44195971原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
    本文鏈接:https://blog.csdn.net/weixin_44195971/article/details/103343836

    智能推薦

    線程的基本概念-馬士兵線程學習筆記

    理解線程 其實搞清楚線程和進程的關系就很好理解線程了。比如說你開一個微信,那微信就是一個進程, 但是微信里你同時和不同的人聊天,那不同的窗口就是一個個線程。線程實際就是可執行程序的最小單元, 是一個進程的不同執行路徑。 線程的兩種創建方式 線程的創建有很多種寫法,但是歸根結底就只有兩種,一種是實現runnable接口,一種是繼承Thread類 熟悉調用線程的幾個函數 sleep() 調用Threa...

    機器學習(1)——基本概念

    轉載自: http://blog.csdn.net/daigualu 一、名詞解釋 數據集(data set)  記錄的集合,假如我們用3個特征,分別為色澤,根蒂,響聲來描述西瓜的特點,并且拿到了基于這3個特征的10萬條記錄,其中一條記錄的取值為: 色澤=光亮,根蒂=堅硬,響聲=清亮  如果記錄到.csv文件中,這個文件的結構可以記為: fruit[100000][3...

    javaScript學習筆記——基本概念

    1.javaScript的定義 ①是一種專門為網頁交互而設計的腳本語言 ② 組成:     2.<script>元素 3.區分大小寫 ECMAScript中的一切(變量、函數名,操作符)都區分大小寫; 4.標識符 ①第一個字符必須是字母、下劃線、$,其他字符可以是字母、下劃線、$或數字; ②ECMAScript標識符一般使用駝峰大小寫格式,即第一個字母小寫,剩下的每...

    HTML中常用操作關于:頁面跳轉,空格

    1.頁面跳轉 2.空格的代替符...

    猜你喜歡

    freemarker + ItextRender 根據模板生成PDF文件

    1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...

    電腦空間不夠了?教你一個小秒招快速清理 Docker 占用的磁盤空間!

    Docker 很占用空間,每當我們運行容器、拉取鏡像、部署應用、構建自己的鏡像時,我們的磁盤空間會被大量占用。 如果你也被這個問題所困擾,咱們就一起看一下 Docker 是如何使用磁盤空間的,以及如何回收。 docker 占用的空間可以通過下面的命令查看: TYPE 列出了docker 使用磁盤的 4 種類型: Images:所有鏡像占用的空間,包括拉取下來的鏡像,和本地構建的。 Con...

    requests實現全自動PPT模板

    http://www.1ppt.com/moban/ 可以免費的下載PPT模板,當然如果要人工一個個下,還是挺麻煩的,我們可以利用requests輕松下載 訪問這個主頁,我們可以看到下面的樣式 點每一個PPT模板的圖片,我們可以進入到詳細的信息頁面,翻到下面,我們可以看到對應的下載地址 點擊這個下載的按鈕,我們便可以下載對應的PPT壓縮包 那我們就開始做吧 首先,查看網頁的源代碼,我們可以看到每一...

    Linux C系統編程-線程互斥鎖(四)

    互斥鎖 互斥鎖也是屬于線程之間處理同步互斥方式,有上鎖/解鎖兩種狀態。 互斥鎖函數接口 1)初始化互斥鎖 pthread_mutex_init() man 3 pthread_mutex_init (找不到的情況下首先 sudo apt-get install glibc-doc sudo apt-get install manpages-posix-dev) 動態初始化 int pthread_...

    精品国产乱码久久久久久蜜桃不卡