主頁 > 企業開發 > 為什么增加一個if(!memcmp())會加快一個在巨大的位元組陣列中隨機短跨度的回圈?

為什么增加一個if(!memcmp())會加快一個在巨大的位元組陣列中隨機短跨度的回圈?

2021-10-20 20:45:14 企業開發

對不起,我從來沒有理解過這里的規則。我已經洗掉了我所發的所有重復的帖子。這是第一個相關的問題。 請不要把這個帖子標記為與我的另一個帖子(將執行次數減少3倍,但執行效率幾乎沒有變化。在C語言中),即使代碼有些相似,它們提出了非常不同的問題。這也是我在同一天發現的兩個問題。一個類似的帖子已經被 "誤判 "重復了,然后被關閉。可能是我沒有弄清楚這個問題。我真的希望能得到答案,所以我重新發了帖子。希望大家都能看清楚這個問題,非常感謝!

在下面的C語言代碼中,我們可以看到 "誤判"。

在下面的C代碼中,我在第一個測驗時間的回圈中加入了一個 "if "陳述句,執行時間完全相同。從理論上講,它應該更慢。盡管分支預測可以使其性能幾乎相同,但實際上卻變得快了很多。這其中的原理是什么?我嘗試使用clang和gcc編譯器分別在Mac和Linux環境下運行,并嘗試了各種優化級別。為了防止快取受到影響,我讓速度快的先執行,但有冗余代碼的回圈執行得更快。

如果你認為我的描述不可信,請將以下代碼編譯到你的電腦中并運行。希望有人能為我解答這個問題,謝謝。

C代碼:

#include <stdio.h>/span>
#include <time.h>
#include <stdlib.h>
#include <string.h>

#define TLen 300000000
#define SLen 10

int main(int argc, const char * argv[]) {
    srandom((unsigned)time(NULL))。
    
    //一個陣列來增加索引,//其元素的范圍是1-256int rand_arr[128] 。
    for (int i = 0; i < 128;   i)
        rand_arr[i] = random()%256 1//一個隨機文本(很長),其元素范圍是0-127char *tex = malloc((sizeof *tex) * TLen) 。
    for (int i = 0; i < TLen;   i)
        tex[i] = random()%128;
    
    //A random string(very short))char *str = malloc((sizeof *str) * SLen) 。
    for (int i = 0; i < SLen;   i)
        str[i] = random()%128//第一次測驗clock_t start = clock();
    for (int i = 0; i < TLen; ) {
        if (!memcmp(tex i, str, SLen)) printf("yes!
")。)
        i  = rand_arr[tex[i]]。
    }
    clock_t end = clock()。
    printf("No.1: %lf s
", ((double) (end - start)) / clocks_per_sec)。)
    
    //第二個測驗for (int i = 0; i < TLen; ) {
        i  = rand_arr[tex[i]]。
    }
    end = clock()。
    printf("No.2: %lf s
", ((double) (end - start)) / clocks_per_sec)。)
    
    return 0。
}

我已經運行了數百次,幾乎都是這個比例。下面是在Linux中測驗的一個代表性結果:

No.10.110000 s
沒有.20.140000 s

uj5u.com熱心網友回復:

關鍵的瓶頸是在跨過tex[]時,作為從舊的i到新的i的依賴鏈的一部分,快取錯過的負載使用延遲。 從小的rand_array[]中的查找將在快取中命中,并且只是在回圈攜帶的依賴鏈中增加了大約5個周期的L1d負載使用延遲,這使得除了通過i的延遲之外,其他的東西更不可能與回圈的整體速度有關。

memcmp(tex i, str, SLen)如果tex i接近快取行的末尾,可能會作為預取的行為。 如果你用-O0編譯,你正在呼叫glibc memcmp,所以在glibc memcmp中完成的SSE 16位元組或AVX2 32位元組的加載跨越了快取行的邊界并拉入下一行。 (IIRC, glibc memcmp檢查并避免page crossing, 但不包括cache-line splits, 因為這些在現代CPU上相對便宜。 單步進入它看看。 進入第二次呼叫,以避免懶惰的動態鏈接,或用-fno-plt)編譯。

可能觸及一些會被隨機stride跳過的快取行有助于HW prefetch更加積極,并將其檢測為一個順序訪問模式。 一個 32 位元組的 AVX 負載是半個高速快取行,所以它相當有可能跨越到下一個高速快取行。

因此,L2 快取看到的更可預測的快取線請求序列是 memcmp 版本更快的一個合理解釋。(Intel CPU 將主要預取器放在 L2。

如果你在編譯時進行了優化,那個 10 位元組的 memcmp 行內和內回圈中只接觸到 8 位元組。 (如果它們匹配,那么它將跳轉到另一個塊,在那里它將檢查最后兩個位元組。 但這種情況極不可能發生)。

這可能就是為什么-O0-O3在我的系統上更快的原因,在i7-6700k Skylake上使用GCC11.1,使用DDR4-2666 DRAM,使用Arch GNU/Linux。 (你的問題沒有說明你的數字來自哪個編譯器和選項,也沒有說明哪個硬體。)

$ gcc -O3 array-stride.c $ taskset -c 3 perf stat --all-user -etask-clock,context-switches,cpu-migrations,page-faults,cycle, instructions,uops_issued.any,uops_executed.thread,mem_load_retired.l1_hit,mem_load_retired.l1_miss -r 2 ./a.out 沒有.10.041710 s 沒有.20.063072 s 沒有.10.040457 s 沒有.20.061166 s 性能計數器統計 for './a.out' (2 運行)。 1,843.71 msec task-clock # 0. 999 CPU utilized ( - 0.14% ) 0背景關系切換 # 0.000 /秒 0 個 cpu-migrations # 0.000 /秒 73,300 次頁面故障 # 39.757 K/sec ( - 0.00% ) 6,607,078,798周期# 3.584 GHz ( - 0.06% )/span> 18,614,303,386條指令#每周期2.82insn ( - 0.00% )/span> 19,407,689,229 uops_issued.any # 10.526 G/sec ( - 0.02% ) 21,970,261,576 uops_executed.thread # 11.916 G/sec ( - 0.02% ) 5,408,090,087 mem_load_retired.l1_hit # 2.933 G/sec ( - 0.00% ) 3,861,687 mem_load_retired.l1_miss # 2.095 M/sec ( - 2.11% ) 1.84537 - 0.00135秒時間 elapsed ( - 0.07% ) $ grep . /sys/devices/system/cpu/cpufreq/policy*/energy_performance_preference /sys/devices/system/cpu/cpufreq/policy0/energy_performance_preference: balance_performance ...在所有8個邏輯核心上都一樣

perf計數器資料基本上沒有意義;它是針對整個運行時間,而不是計時區域(在1.8秒中大約有0.1秒),所以這里的大部分時間是在glibc random(3),它使用"一個非線性加性反饋亂數發生器,采用大小為31長整數的默認表"。 也是在大malloc區域的頁面故障中。

這只是一個有趣的例子。

這只是在兩次構建之間的delta方面比較有趣,但是在定時區域之外的回圈仍然貢獻了許多額外的uops,所以它仍然沒有像人們希望的那樣有趣。


vs.

vs. gcc -O0: No.1 更快,No.2 正如預期的那樣更慢,-O0 在涉及 i 的依賴鏈中加入了一個存盤/重新加載。

$ gcc -O0 array-stride.c
$ taskset -c 3 perf stat --all-user -etask-clock,context-switches,cpu-migrations,page-faults,cycle, instructions,uops_issued.any,uops_executed.thread,mem_load_retired.l1_hit,mem_load_retired.l1_miss -r 2 . / a.out 
沒有.10.028402 s
沒有.20.076405 s
沒有.10.028079 s
沒有.20.069492 s

 性能計數器統計for './a.out'2運行)。

          1,979.57 msec task-clock # 0. 999 CPU utilized (  - 0.04% ) 
                 0背景關系切換 # 0.000 /秒                   
                 0 個 cpu-migrations # 0.000 /秒                   
            66,656 次頁面故障 # 33.672 K/sec (  - 0.00% )
     7,252,728,414周期# 3.664 GHz (  - 0.02% )/span>
    20,507,166,672條指令# 每周期2.83insn (  - 0.01% )/span>
    22,268,130,378 uops_issued.any # 11.249 G/sec (  - 0.00% ) 
    25,117,638,171 uops_executed.thread # 12.688 G/sec (  - 0.00% ) 
     6,640,523,801 mem_load_retired.l1_hit # 3.355 G/sec (  - 0.01% ) 
         3,350,518 mem_load_retired.l1_miss # 1.693 M/sec (  - 1.39% ) /-span>

         1.9810591  - 0.0000934秒時間 elapsed (  - 0.00% ) 

記住這個分析是針對運行時間的,而不是針對定時區域的,所以2.83的IPC不是針對定時區域的。


失序執行器隱藏獨立作業的成本

運行那個宏融合的cmp/je uop的實際吞吐量成本并沒有增加任何瓶頸,這要感謝out-of-order exec。 甚至整個call memcmp@plt和設定args。 瓶頸是延遲,而不是前端,或者后端的負載埠,而且OOO執行視窗足夠深,可以隱藏memcmp的作業。 也請看下面的內容來了解現代CPU。 (是的,這需要大量的閱讀才能把你的頭緒搞清楚。)

通過i的回圈攜帶的依賴性去i -> tex[i] -> 間接回到i進行下一次迭代,單調地增加它。 tex[]太大,無法放入快取,而硬體預取也無法跟上這些步伐。

因此,DRAM 的帶寬可能是限制因素,甚至是 DRAM 的延遲,如果 HW 預取不能檢測并鎖定連續或每隔一個快取行的有點順序的訪問模式。

實際的分支預測非常完美,因此它可以在加載結果到達時執行(并確認預測),與等待在同一地點開始的符號擴展位元組加載的東西并行。

而且執行時間是完全一樣的。......它實際上變得快了很多。

嗯?你的時間并沒有顯示完全相同。 是的,有了那個memcmp,它確實變得可觀地快了。

在理論上,它應該更慢。

在理論上,它應該更慢。

只有在你的理論過于簡單,無法模擬現代 CPU 的情況下才會如此。 不放慢速度是很容易解釋的,因為在等待負載延遲時,有多余的失序執行吞吐量來完成該獨立作業。

對于-O0性能來說,也可能與之相關:


作為參考,# gcc11.1 -O0 -fPIE .L10: # do{[/span]}. mov eax, DWORD PTR -16[rbp] movsx rdx, eax mov rax, QWORD PTR -32[rbp] 。 LEA RCX, [RDX RAX]。 mov rax, QWORD PTR -40[rbp] 。 mov edx, 10[rbp]。 mov rsi, rax mov rdi, rcx 呼叫memcmp@PLT 測驗eax, eax jne .L9 # 通常采取跳過put。 lea rax, .LC0[rip] mov rdi, rax 呼叫puts@PLT .L9: mov eax, DWORD PTR -16[rbp] movsx rdx, eax mov rax, QWORD PTR -32[rbp] add rax, rdx # strange not using an addressing mode, but ok[rbp] 。 movzx eax, BYTE PTR [rax]. movsx eax, al # GCC -O0是個蠢貨。 cdqe # really dumb. mov eax, DWORD PTR -576[rbp rax*4] # look up in rand_array[]/span> 添加DWORD PTR -16[rbp], eax # i = ..._/span> .L8: cmp DWORD PTR -16[rbp], 2999999[/span]. jle .L10 # }while(i<300000000)

與-O3的代碼相比:

# RBP持有char *tex在這一點上。
.L10: # do{[/span]}。
        movsx r12, r13d # sign-extend i
        mov rax, QWORD PTR [rbx] # str[0...7] 被重新加載,因為別名分析和可能的puts呼叫使優化器失敗。 避免使用malloc可能會有幫助。
        添加r12, rbp # i tex以避免以后的索引尋址模式? 可能不是最佳選擇
        cmp QWORD PTR [r12], rax # 前8位元組的memcmp
        je .L18 # 在.L18處的代碼會檢查接下來的2個位元組,也許會做puts,然后再跳回去。
.L5:
        movsx rax, BYTE PTR [r12] # sign-extending byte load to pointer width, of tex[i] .
        add r13d, DWORD PTR [rsp rax*4] # i  = look up in rand_array[]/span>
        cmp r13d, 299999999 
        jle .L10 # }while(i < 300000000)

由于je .L18從未被占用,因此每次迭代有7個uops,所以Skylake可以在每次迭代的2個周期內自如地發布它。

即使有 L1d 快取命中,通過 i (R13D) 的回圈攜帶的依賴性也是:

因此,在L1d命中的情況下,總共約有13個周期的延遲最佳,在前端留下大量的空閑 "槽",以及空閑的后端執行單元,即使呼叫實際的glibc memcmp也沒什么大不了的。

(當然,-O0代碼更加嘈雜,所以流水線區域的一些空閑槽已經用完了,但是由于-O0代碼將i保留在記憶體中,所以dep鏈甚至更長。為什么clang用-O0(對于這個簡單的浮點和)產生低效的asm?)


記憶體瓶頸回圈中的CPU頻率,尤其是在Skylake上。

初始回圈為 CPU 提供了充足的時間,使其在定時區域之前達到最大渦輪增壓,并通過先觸及分配的頁面來預發故障。 性能評估的自動方式?

如果在那些等待快取缺失負載的傳入資料的程序中,有更多的作業,更少的停頓,那么保持CPU頻率更高的效果也可能存在。 請參閱通過施加記憶體壓力來降低 CPU 頻率

在上述結果中,我使用 EPP = balance_performance進行測驗。

我還用performance進行了測驗,-O0(libc memcmp)仍然比-O3(inlined memcmp)快,但所有4個回圈確實都加快了一些(有/無memcmp,以及優化與否)。







編譯器/CPU No.1 if(memcmp) No.2 plain
-O0 / balance_performance 0.028079 s 0.069492 s
0.069492 s?





-O0 / performance 0.026898 s
0.053805 s
0.053805 s 0.053805 s
-O3 / balance_performance 0.040457 s
0.061166
0.061166 s?





-O3 / performance 0.035621 s
0.0474 s 0.047475 s
0.035621 s?

即使在EPP=performance的情況下,更快的O0效應仍然存在,而且非常顯著,所以我們知道這不是just一個時鐘速度的問題。 從以前的實驗來看,performance使它保持在最大的渦輪增壓狀態,即使在其他設定將時鐘從4.2GHz降到2.7GHz的情況下。 因此,呼叫 memcmp 很可能有助于觸發更好的預取,以減少平均快取缺失延遲。

不幸的是,我沒有為 PRNG 使用一個固定的種子,所以可能會有一些變化,因為隨機性對預取器來說是好是壞,就整個快取行的訪問模式而言。 而且我只是為每一個特定的運行(由 perf stat -r 2 啟動的一對中的第二個,所以希望它應該更少地受到系統波動的影響。

看起來performance對No.2回圈(其中發生的事情較少)和-O3版本(其中發生的事情同樣較少)產生了較大的影響,這與Skylake在performance以外的EPP設定中,當一個核心幾乎只在記憶體上遇到瓶頸而不運行許多其他指令時降低時鐘速度是一致的。

uj5u.com熱心網友回復:

簡短的回答,也是純粹的猜測。在第一個定時回圈中,由tex指向的緩沖區在初始化后仍在快取中。printf做了很多復雜的事情,包括內核呼叫,任何快取行現在很可能被其他資料填滿。

第二個定時回圈現在必須從 RAM 重新讀取資料。

嘗試交換回圈,和/或將printf延遲到兩次測量之后。

哦,對memcmp的呼叫有可能出現緩沖區溢位。

轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/326840.html

標籤:

上一篇:laravel錯誤"ArgumentCountErrorToofewargumentstofunctionAppHttpControllersUserController::magesend

下一篇:減少3倍的執行次數,但執行效率幾乎沒有變化。在C

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • IEEE1588PTP在數字化變電站時鐘同步方面的應用

    IEEE1588ptp在數字化變電站時鐘同步方面的應用 京準電子科技官微——ahjzsz 一、電力系統時間同步基本概況 隨著對IEC 61850標準研究的不斷深入,國內外學者提出基于IEC61850通信標準體系建設數字化變電站的發展思路。數字化變電站與常規變電站的顯著區別在于程序層傳統的電流/電壓互 ......

    uj5u.com 2020-09-10 03:51:52 more
  • HTTP request smuggling CL.TE

    CL.TE 簡介 前端通過Content-Length處理請求,通過反向代理或者負載均衡將請求轉發到后端,后端Transfer-Encoding優先級較高,以TE處理請求造成安全問題。 檢測 發送如下資料包 POST / HTTP/1.1 Host: ac391f7e1e9af821806e890 ......

    uj5u.com 2020-09-10 03:52:11 more
  • 網路滲透資料大全單——漏洞庫篇

    網路滲透資料大全單——漏洞庫篇漏洞庫 NVD ——美國國家漏洞庫 →http://nvd.nist.gov/。 CERT ——美國國家應急回應中心 →https://www.us-cert.gov/ OSVDB ——開源漏洞庫 →http://osvdb.org Bugtraq ——賽門鐵克 →ht ......

    uj5u.com 2020-09-10 03:52:15 more
  • 京準講述NTP時鐘服務器應用及原理

    京準講述NTP時鐘服務器應用及原理京準講述NTP時鐘服務器應用及原理 安徽京準電子科技官微——ahjzsz 北斗授時原理 授時是指接識訓通過某種方式獲得本地時間與北斗標準時間的鐘差,然后調整本地時鐘使時差控制在一定的精度范圍內。 衛星導航系統通常由三部分組成:導航授時衛星、地面檢測校正維護系統和用戶 ......

    uj5u.com 2020-09-10 03:52:25 more
  • 利用北斗衛星系統設計NTP網路時間服務器

    利用北斗衛星系統設計NTP網路時間服務器 利用北斗衛星系統設計NTP網路時間服務器 安徽京準電子科技官微——ahjzsz 概述 NTP網路時間服務器是一款支持NTP和SNTP網路時間同步協議,高精度、大容量、高品質的高科技時鐘產品。 NTP網路時間服務器設備采用冗余架構設計,高精度時鐘直接來源于北斗 ......

    uj5u.com 2020-09-10 03:52:35 more
  • 詳細解讀電力系統各種對時方式

    詳細解讀電力系統各種對時方式 詳細解讀電力系統各種對時方式 安徽京準電子科技官微——ahjzsz,更多資料請添加VX 衛星同步時鐘是我京準公司開發研制的應用衛星授時時技術的標準時間顯示和發送的裝置,該裝置以M國全球定位系統(GLOBAL POSITIONING SYSTEM,縮寫為GPS)或者我國北 ......

    uj5u.com 2020-09-10 03:52:45 more
  • 如何保證外包團隊接入企業內網安全

    不管企業規模的大小,只要企業想省錢,那么企業的某些服務就一定會采用外包的形式,然而看似美好又經濟的策略,其實也有不好的一面。下面我通過安全的角度來聊聊使用外包團的安全隱患問題。 先看看什么服務會使用外包的,最常見的就是話務/客服這種需要大量重復性、無技術性的服務,或者是一些銷售外包、特殊的職能外包等 ......

    uj5u.com 2020-09-10 03:52:57 more
  • PHP漏洞之【整型數字型SQL注入】

    0x01 什么是SQL注入 SQL是一種注入攻擊,通過前端帶入后端資料庫進行惡意的SQL陳述句查詢。 0x02 SQL整型注入原理 SQL注入一般發生在動態網站URL地址里,當然也會發生在其它地發,如登錄框等等也會存在注入,只要是和資料庫打交道的地方都有可能存在。 如這里http://192.168. ......

    uj5u.com 2020-09-10 03:55:40 more
  • [GXYCTF2019]禁止套娃

    git泄露獲取原始碼 使用GET傳參,引數為exp 經過三層過濾執行 第一層過濾偽協議,第二層過濾帶引數的函式,第三層過濾一些函式 preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'] (?R)參考當前正則運算式,相當于匹配函式里的引數 因此傳遞 ......

    uj5u.com 2020-09-10 03:56:07 more
  • 等保2.0實施流程

    流程 結論 ......

    uj5u.com 2020-09-10 03:56:16 more
最新发布
  • 使用Django Rest framework搭建Blog

    在前面的Blog例子中我們使用的是GraphQL, 雖然GraphQL的使用處于上升趨勢,但是Rest API還是使用的更廣泛一些. 所以還是決定回到傳統的rest api framework上來, Django rest framework的官網上給了一個很好用的QuickStart, 我參考Qu ......

    uj5u.com 2023-04-20 08:17:54 more
  • 記錄-new Date() 我忍你很久了!

    這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 大家平時在開發的時候有沒被new Date()折磨過?就是它的諸多怪異的設定讓你每每用的時候,都可能不小心踩坑。造成程式意外出錯,卻一下子找不到問題出處,那叫一個煩透了…… 下面,我就列舉它的“四宗罪”及應用思考 可惡的四宗罪 1. Sa ......

    uj5u.com 2023-04-20 08:17:47 more
  • 使用Vue.js實作文字跑馬燈效果

    實作文字跑馬燈效果,首先用到 substring()截取 和 setInterval計時器 clearInterval()清除計時器 效果如下: 實作代碼如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta ......

    uj5u.com 2023-04-20 08:12:31 more
  • JavaScript 運算子

    JavaScript 運算子/運算子 在 JavaScript 中,有一些運算子可以使代碼更簡潔、易讀和高效。以下是一些常見的運算子: 1、可選鏈運算子(optional chaining operator) ?.是可選鏈運算子(optional chaining operator)。?. 可選鏈操 ......

    uj5u.com 2023-04-20 08:02:25 more
  • CSS—相對單位rem

    一、概述 rem是一個相對長度單位,它的單位長度取決于根標簽html的字體尺寸。rem即root em的意思,中文翻譯為根em。瀏覽器的文本尺寸一般默認為16px,即默認情況下: 1rem = 16px rem布局原理:根據CSS媒體查詢功能,更改根標簽的字體尺寸,實作rem單位隨螢屏尺寸的變化,如 ......

    uj5u.com 2023-04-20 08:02:21 more
  • 我的第一個NPM包:panghu-planebattle-esm(胖虎飛機大戰)使用說明

    好家伙,我的包終于開發完啦 歡迎使用胖虎的飛機大戰包!! 為你的主頁添加色彩 這是一個有趣的網頁小游戲包,使用canvas和js開發 使用ES6模塊化開發 效果圖如下: (覺得圖片太sb的可以自己改) 代碼已開源!! Git: https://gitee.com/tang-and-han-dynas ......

    uj5u.com 2023-04-20 08:01:50 more
  • 如何在 vue3 中使用 jsx/tsx?

    我們都知道,通常情況下我們使用 vue 大多都是用的 SFC(Signle File Component)單檔案組件模式,即一個組件就是一個檔案,但其實 Vue 也是支持使用 JSX 來撰寫組件的。這里不討論 SFC 和 JSX 的好壞,這個仁者見仁智者見智。本篇文章旨在帶領大家快速了解和使用 Vu ......

    uj5u.com 2023-04-20 08:01:37 more
  • 【Vue2.x原始碼系列06】計算屬性computed原理

    本章目標:計算屬性是如何實作的?計算屬性快取原理以及洋蔥模型的應用?在初始化Vue實體時,我們會給每個計算屬性都創建一個對應watcher,我們稱之為計算屬性watcher ......

    uj5u.com 2023-04-20 08:01:31 more
  • http1.1與http2.0

    一、http是什么 通俗來講,http就是計算機通過網路進行通信的規則,是一個基于請求與回應,無狀態的,應用層協議。常用于TCP/IP協議傳輸資料。目前任何終端之間任何一種通信方式都必須按Http協議進行,否則無法連接。tcp(三次握手,四次揮手)。 請求與回應:客戶端請求、服務端回應資料。 無狀態 ......

    uj5u.com 2023-04-20 08:01:10 more
  • http1.1與http2.0

    一、http是什么 通俗來講,http就是計算機通過網路進行通信的規則,是一個基于請求與回應,無狀態的,應用層協議。常用于TCP/IP協議傳輸資料。目前任何終端之間任何一種通信方式都必須按Http協議進行,否則無法連接。tcp(三次握手,四次揮手)。 請求與回應:客戶端請求、服務端回應資料。 無狀態 ......

    uj5u.com 2023-04-20 08:00:32 more