中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當前位置: 首頁 > news >正文

建設企業(yè)外貿(mào)網(wǎng)站如何優(yōu)化網(wǎng)絡速度

建設企業(yè)外貿(mào)網(wǎng)站,如何優(yōu)化網(wǎng)絡速度,昆山玉山網(wǎng)站建設,怎么自己做網(wǎng)站的推廣緒論 大家好,歡迎來到【程序員的自我修養(yǎng)】專欄。正如其專欄名,本專欄主要分享學習《程序員的自我修養(yǎng)——鏈接、裝載與庫》的知識點以及結(jié)合自己的工作經(jīng)驗以及思考。編譯原理相關(guān)知識本身就比較有難度,我會盡自己最大的努力,爭取…

緒論

????????大家好,歡迎來到【程序員的自我修養(yǎng)】專欄。正如其專欄名,本專欄主要分享學習《程序員的自我修養(yǎng)——鏈接、裝載與庫》的知識點以及結(jié)合自己的工作經(jīng)驗以及思考。編譯原理相關(guān)知識本身就比較有難度,我會盡自己最大的努力,爭取深入淺出。若你希望與一群志同道合的朋友一起學習,也希望加入到我們的學習群中。文末有加入方式。

簡介

????????本文主要介紹我們熟悉的編譯四大流程:預處理,編譯,匯編,鏈接。因為是我們經(jīng)常會討論的話題,因此會盡可能詳細討論一下其中的細節(jié)。不會太難,大家要跟上腳步哦。

????????本文討論的示例代碼如下:

//helloworld.h
extern int printf(const char *format, ...);#if 1#define HELLOWORLD "hello world 1\n"
#else#define HELLOWORLD "hello world 2\n"
#endif
//helloworld.c
#include<helloworld.h>
int main()
{printf(HELLOWORLD);return 0;
}

預處理

????????命令:gcc -E helloworld.c -I. -o helloworld.i其中-I.表示頭文件搜索路徑。

????????預處理主要處理哪些源代碼文件中的以"#"開始的預編譯指令。比如"#define"、"#include"等。主要的規(guī)則有:

  • 處理所有條件預編譯指令,比如"#if"、"#ifdef"、"#elif"、"#else"、"#endif"等。
  • 將所有的"#define"刪除,并展開所有的宏定義。
  • 處理"#include"預編譯指令,將被包含的文件插入到該預編譯指令的位置(可以代碼中利用這個特性)。注意,這個過程是遞歸進行的。
  • 刪除所有的注釋"//"和"/* */"。這也就是說明,詳細的代碼注釋,并不會造成目標文件變大。
  • 添加行號和文件名標識,比如#2 “hello world.c” 2,以便于編譯時編譯器產(chǎn)生調(diào)試用的行號信息、編譯錯誤或編譯警告時顯示行號。
  • 保留所有的#pragma 編譯器指令,因為編譯器需要使用它們。

helleworld.i 內(nèi)容如下,請根據(jù)上面規(guī)則,仔細對比一下。

# 1 "helloworld.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 31 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 32 "<command-line>" 2
# 1 "helloworld.c"
# 1 "./helloworld.h" 1
extern int printf(const char *format, ...);
# 2 "helloworld.c" 2int main()
{printf("hello world 1\n");return 0;
}

????????注:工作中經(jīng)常會遇到類似fatal error: xxxxxx.h: No such file or directory錯誤,就是在預編譯階段體現(xiàn)的。

????????但是預編譯階段不會進行語法校驗,類似如下的編碼,并不會提示錯誤。

編譯

????????編譯階段是整個程序構(gòu)建的核心部分,也是最復雜的部分。它主要對文件進行詞法分析、語法分析、語義分析及優(yōu)化生成的匯編代碼文件。

????????命令:gcc -S helloworld.i -o helloworld.s?或者 /usr/lib/gcc/x86_64-linux-gnu/9/cc1 helloworld.i。其中cc1文件的路徑,不同的操作系統(tǒng)可能不一致。我的虛擬機是ubunt 18.04 版本。

helloworld.s 內(nèi)容如下:

        .file   "helloworld.i".text.section        .rodata
.LC0:.string "hello world 1".text.globl  main.type   main, @function
main:
.LFB0:.cfi_startprocpushq   %rbp.cfi_def_cfa_offset 16.cfi_offset 6, -16movq    %rsp, %rbp.cfi_def_cfa_register 6leaq    .LC0(%rip), %rdicall    puts@PLTmovl    $0, %eaxpopq    %rbp.cfi_def_cfa 7, 8ret.cfi_endproc
.LFE0:.size   main, .-main.ident  "GCC: (Ubuntu 9.4.0-1ubuntu1~18.04) 9.4.0".section        .note.GNU-stack,"",@progbits

????????因為我不是從事自然語言研究方向,編譯階段的詞法分析、語法分析、語義分析就不再進一步展開。但是其中的優(yōu)化還是需要略微深入一下。因為編譯器優(yōu)化,其中也存在一些坑。

編譯器優(yōu)化

????????編譯器優(yōu)化的目的:優(yōu)化程序的性能減少代碼的生成。因此有時候提高編譯優(yōu)化等級,可以稍微提高程序的執(zhí)行效率。常見的方式有以下幾種:

1. 常量傳播。能夠直接計算出結(jié)果的變量,將被編譯器由直接結(jié)果來替代。例如:

{int x = 10;printf("x = %d\n",x);
}
優(yōu)化后:
{printf("x = %d\n",10);
}

2. 常量折疊。如果有可能,多個變量的計算可以最終替換成為一個變量的計算。例如:

{int a = 1;int b = 2;int c = a + b;printf("c = %d\n",c);
}
優(yōu)化后:
{int c = 1 + 2;printf("c = %d\n",c);
}
再結(jié)合 1.優(yōu)化方式,得
{printf("c = %d\n",3);
}

3. 復寫傳播。用一個變量替換兩個或多個相同的變量。例如:

{int a = 1;int b = a;printf("b = %d\n",b);
}
優(yōu)化后:
{int b = 1;printf("b = %d\n",b);
}

4. 公共表達式消除。如果一個表達式已經(jīng)計算過了,并且從先前的計算到現(xiàn)在的E中的變量都沒有發(fā)生變化,那么E的此次出現(xiàn)就成為了公共表達式,編譯器不需要再次進行計算浪費性能。例如:

{int a = 1;int b = 2;int c = (a+b) * 2 + (b+a) * 6;
}
優(yōu)化后:
{int a = 1;int b = 2;int E = a + b;int c = E * 2 + E * 6;
}

5. 無用代碼消除。將永遠不能執(zhí)行到的代碼或沒有任何意義的代碼清除。比如return 之后的代碼、未使用的變量、變量給自己賦值等。

6. 數(shù)組范圍檢查消除。Java這種動態(tài)類型安全型的,那在訪問數(shù)組時比如array[ ]時,Java不會像C/C++那樣只是純粹的裸指針訪問,而是會在運行時訪問數(shù)組元素前進行一次是否越界檢查,這將會帶來許多開銷如果即時編譯器能根據(jù)數(shù)據(jù)流分析出變量的取值范圍在[0,array.length]之間,那么在循環(huán)期間就可以把數(shù)組的上下邊界檢查消除,以減少不必要的性能損耗。

7. 方法內(nèi)聯(lián)。將比較簡短的函數(shù)或方法直接粘貼到其調(diào)用者中,以減少函數(shù)調(diào)用時的開銷。例如:

int test()
{printf("i'm test\n");
}
{int a = 1;test();int b = 2;
}
優(yōu)化后:
{int a = 1;printf("i'm test\n");int b = 2;
}

8. 逃逸分析。逃逸分析的基本原理就是分析對象動態(tài)作用域。如果確定一個方法不會逃逸出方法之外,那讓整個對象在棧上分配內(nèi)存將會是一個很不錯的主意,對象所占用的內(nèi)存空間就可以隨棧幀而銷毀。在一般應用中,不會逃逸的局部對象所占用的比例很大,如果能在編譯器優(yōu)化時,為其在棧上分配內(nèi)存空間,那大量的對象就會隨著方法結(jié)束而自動銷毀了,不用依賴前面講的GC或者記憶力,系統(tǒng)的壓力將會小很多。

編譯器優(yōu)化的坑

????????編譯器優(yōu)化帶來的問題有很多場景,在網(wǎng)上搜索的話,應該有很多實際案例。可以參看這兩個案例:

不同優(yōu)化選項對ARM下C語言編譯的影響 - 守夜者 - 博客園

關(guān)于O2編譯選項的一個過優(yōu)化問題及其解決方法_o2優(yōu)化-CSDN博客

匯編

????????匯編過程就是將匯編文件轉(zhuǎn)換為機器可以執(zhí)行的指令。因此它的內(nèi)部邏輯比較單一,僅需要將匯編語句對照表格一一翻譯即可。

????????命令:gcc -c helloworld.s -o helloworld.oas helloworld.s -o helloworld.o亦或gcc -c helloworld.c -o helloworld.o。

問題:x86環(huán)境的虛擬機為什么想反匯編(objdump -d *.so)arm 平臺的動態(tài)庫,失敗呢?

答:我們在工作中,經(jīng)常會遇到一些問題,需要查看動態(tài)庫的信息,比如查看依賴庫,反匯編,甚至是gdb調(diào)試。但是嵌入式平臺的資源有限,一般是不會集成相關(guān)工具的。常見的方式就是將目標文件copy到本地虛擬環(huán)境中,進行調(diào)試。但是我們往往用objdump,gdb等工具時,提示如下失敗:

其原因:.o、.so、可執(zhí)行程序都已經(jīng)是二進制文件,是對應機器可識別的指令。而嵌入式平臺一般都是arm架構(gòu),開發(fā)電腦是x86,兩套架構(gòu)識別的指令不一致,所以不能解析對方的機器碼。若想在虛擬機中調(diào)試其他平臺的動態(tài)庫或可執(zhí)行程序,需要使用交叉編譯工具鏈中的對應工具。

鏈接

????????鏈接才是我們整個過程中最為復雜的過程,這個階段做了很多很多事情。因此出現(xiàn)異常的概率也高。大致可以分為兩個范圍。

  • 靜態(tài)鏈接過程。主要指生成動態(tài)庫或可執(zhí)行文件的過程。比如:工作中,我們經(jīng)常遇到工程編譯提示錯誤,大部分都是在鏈接階段提示的。
  • 動態(tài)鏈接過程。就是程序運行過程。我們知道若程序依賴動態(tài)庫,那么程序在真正運行前,需要找到對應的動態(tài)庫并加載。常見的問題就是找不到對應動態(tài)庫,或?qū)栒也坏?#xff1b;有時會出現(xiàn)匪夷所思的現(xiàn)象。有興趣的可以了解我遇到的一個案例:坑慘啦!!!——符號沖突案例分析-CSDN博客

????????為了不打擊大家的信心,本篇文章不會再進一步展開討論。后續(xù)我會慢慢揭開鏈接過程的面紗,其實也就那么一回事。

????????不過大家可以先思考以下幾個問題,嘗試猜測鏈接做了哪些事情。

一、helloworld.o 中引用了printf方法,程序運行時,它是怎么知道符號地址的呢?該跳轉(zhuǎn)到哪里,繼續(xù)執(zhí)行程序呢

二、程序正真運行前,需要做哪些事情呢動態(tài)庫加載、符號重定位其大致邏輯如何呢

技巧分享

本章節(jié)主要和大家分享一下,我工作中用到的小技巧,也歡迎大家在評論區(qū)補充,我會更新到文章中。

一、利用"#include",更好的維護代碼。

????????我們知道#include是預處理過程中將文件內(nèi)容加載到對應位置的操作。那么我們可以將一些可變的信息保存在文件中,那么就不會更改我們的.c 源文件。

????????比如:做過單片機LCD顯示的朋友,肯定知道每一張照片信息,其實就是一個超大的整型數(shù)組。常見的方式如下:

//picture.c
int picture_data[] = {*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,
}

每當圖片信息變化時,則需要更新picture_data數(shù)組里面的信息,也就要更改picture.c源文件。我覺得這樣并不友好。優(yōu)化如下:

//picture_data.h
{*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,
}//picture_data.c
int picture_data[] = 
#include<picture.h>
;

這樣每次圖片更新,僅需要替換picture_data.h文件即可。

二、如何快速確認"#if"、"#ifdef"、"#elif"、"#else"、"#endif" 的實際分支。

????????在大型的工程項目中,隨著需求的迭代代碼分支也比較多,經(jīng)常會用到類似"if"、"#ifdef"、"#elif"、"#else"、"#endif" 等分支控制方式。這就導致我們有時不知道實際代碼編譯的是哪一部分。我的快速定位的方式就是在對應的分支中加上亂碼。比如:

亦或者加上錯誤提示:

再多問一下,大家知道上面兩種方式的不同嗎?(提示一下,不同的階段。)

總結(jié)

????????以上便是本文的內(nèi)容,我們回顧了編譯的四大過程:預處理,編譯,匯編,鏈接。以及每個過程大致做了哪些事,可能會遇到的問題;也知道了編譯器優(yōu)化帶來的可能弊端,因此編譯器的優(yōu)化選項我們要慎重,如果對效率要求不高,建議開啟O1即可;鏈接階段是一大難點,本文沒有展開敘述,但是通過案例和拋出的問題,我相信,大家對鏈接肯定產(chǎn)生了莫大的興趣。請別著急,關(guān)注專欄,后續(xù)一定會娓娓道來。

????????有任何相關(guān)問題歡迎留言討論,我會盡快回復。

????????若您正遇到相關(guān)問題,苦于沒有一群志同道合的朋友交流,探討。也歡迎加入我們的討論組群??赏ㄟ^私聊我,我會盡快拉你進群。

http://m.risenshineclean.com/news/48201.html

相關(guān)文章:

  • wordpress 眾籌模板優(yōu)化大師免費版下載
  • 中企動力做網(wǎng)站服務怎么樣seo網(wǎng)絡推廣報價
  • 設計網(wǎng)站推薦平面網(wǎng)頁制作作業(yè)100例
  • 怎樣用h5做網(wǎng)站素材網(wǎng)
  • 網(wǎng)站備案照怎么開網(wǎng)站
  • 怎么看網(wǎng)站是dede模板品牌宣傳推廣文案
  • 網(wǎng)站有了域名后怎么還上不了常州seo外包
  • 網(wǎng)站搭建官網(wǎng)個人怎么做網(wǎng)站
  • 手機怎么做網(wǎng)站添加背景音樂建網(wǎng)站找哪個平臺好呢
  • 佛山有那些定制網(wǎng)站建設公司百度貼吧官網(wǎng)入口
  • 成都區(qū)塊鏈網(wǎng)站開發(fā)競價外包推廣專業(yè)公司
  • 農(nóng)村建設房子建設網(wǎng)站建設外鏈下載
  • vi設計英文seo點擊排名源碼
  • 外外貿(mào)網(wǎng)站推廣方案hao123網(wǎng)址導航
  • 個體工商戶可以搞網(wǎng)站建設離我最近的電腦培訓中心
  • 裝飾裝潢seo怎么做優(yōu)化方案
  • 日本真人做爰無遮擋視頻免費網(wǎng)站網(wǎng)絡推廣培訓去哪里好
  • 深圳網(wǎng)站建設 網(wǎng)站設計亞馬遜查關(guān)鍵詞排名工具
  • 網(wǎng)站常用的藍色2023國內(nèi)外重大新聞事件10條
  • 品牌網(wǎng)站升級網(wǎng)絡營銷推廣策劃書
  • 在福州做搬家網(wǎng)站多少錢seo快速排名點擊
  • 邯鄲網(wǎng)站建設的地方考研培訓班集訓營
  • 南通網(wǎng)站建設報價社交網(wǎng)絡推廣方法
  • 手機制作網(wǎng)站主頁軟件下載百度網(wǎng)盤
  • 網(wǎng)站被取消備案福州seo博客
  • 個人做網(wǎng)站要備案嗎安徽網(wǎng)站關(guān)鍵詞優(yōu)化
  • 做阿里巴巴網(wǎng)站圖片大全企業(yè)官網(wǎng)網(wǎng)站
  • 羅湖做網(wǎng)站58優(yōu)化網(wǎng)站關(guān)鍵詞的技巧
  • 做煤的網(wǎng)站app網(wǎng)站需要怎么優(yōu)化比較好
  • 東莞公司建設網(wǎng)站如何在百度上推廣自己