精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

深入理解 CPU 緩存:編寫高性能 Java 代碼的終極指南

開發(fā)
本文將從計算機(jī)體系結(jié)構(gòu)的發(fā)展歷程出發(fā),深入剖析CPU緩存的核心原理,并結(jié)合豐富的Java代碼示例,揭示那些隱藏在底層硬件之下的性能優(yōu)化技巧,幫助您寫出真正高效的程序。

在當(dāng)今高性能計算的時代,程序性能已不再僅僅取決于算法的復(fù)雜度,更深層次地依賴于對底層硬件的理解與利用。CPU緩存作為連接處理器與內(nèi)存的關(guān)鍵橋梁,直接影響著程序的運行效率。隨著CPU主頻提升逐漸逼近物理極限,架構(gòu)層面的優(yōu)化,尤其是緩存機(jī)制的合理利用,成為提升軟件性能的核心突破口。

CPU緩存通過“局部性原理”將熱點數(shù)據(jù)預(yù)加載至高速緩存中,大幅減少CPU等待數(shù)據(jù)的時間。從最初的單級緩存到如今的多級緩存體系,從直接映射到組相聯(lián)映射,緩存技術(shù)的演進(jìn)不僅體現(xiàn)了計算機(jī)體系結(jié)構(gòu)設(shè)計者的智慧,也為我們編寫高性能代碼提供了底層支持。

但僅僅知道緩存的存在是遠(yuǎn)遠(yuǎn)不夠的。作為一名Java開發(fā)者,深入理解CPU緩存的工作機(jī)制,并將其應(yīng)用于實際開發(fā)中,是邁向高性能編程的關(guān)鍵一步。無論是數(shù)組的訪問順序、分支預(yù)測的優(yōu)化,還是多核環(huán)境下線程與CPU核心的綁定策略,每一個細(xì)節(jié)都可能帶來數(shù)量級級別的性能差異。

本文將從計算機(jī)體系結(jié)構(gòu)的發(fā)展歷程出發(fā),深入剖析CPU緩存的核心原理,并結(jié)合豐富的Java代碼示例,揭示那些隱藏在底層硬件之下的性能優(yōu)化技巧,幫助您寫出真正高效的程序。

一、回顧計算機(jī)體系

1. 馮諾依曼計算機(jī)體系

早期的馮諾依曼計算機(jī),大抵功能和工作流程如下:

  • 輸入設(shè)備接收用戶輸入的指令信息
  • 數(shù)據(jù)到達(dá)存儲器,控制器從存儲器中取出指令交給運算器執(zhí)行
  • 控制器從存儲器中撈數(shù)據(jù)和指令交給運算器完成運算,最后交由輸出設(shè)備響應(yīng)給用戶

可以看到控制流程的調(diào)度由運算器負(fù)責(zé),導(dǎo)致一個簡單的執(zhí)行需要經(jīng)過多個不必要的工序,使得整個執(zhí)行流程變得繁瑣冗長:

2. 現(xiàn)代計算機(jī)

現(xiàn)在計算機(jī)對此進(jìn)行了改造,可以看出他們將需要處理的數(shù)據(jù)的運算器和存儲器放到兩邊,然后存儲器負(fù)責(zé)運輸數(shù)據(jù)給這兩者,數(shù)據(jù)經(jīng)過運算器計算之后再將數(shù)據(jù)經(jīng)過存儲器再轉(zhuǎn)交給控制器轉(zhuǎn)發(fā)到輸出設(shè)備:

了解這樣的體系結(jié)構(gòu)后,我們將這些組成部分整合起來,就得到了現(xiàn)代計算機(jī)的重要組成部分——CPU。CPU包含了運算器和控制器,主存儲器(也就是我們常說的內(nèi)存)以及輔存(就是硬盤):

我們將職責(zé)進(jìn)行劃分就構(gòu)成了下圖所示的樣子:

  • 由運算器和控制器構(gòu)成CPU
  • 主存也就是我們常說的內(nèi)存
  • 外設(shè)部分由一些I/O設(shè)備、輔存(就是硬盤)組成

二、詳解cpu緩存

1. 內(nèi)存性能的局限性

計算機(jī)發(fā)展初期,CPU執(zhí)行指令時用到的數(shù)據(jù)都必須從內(nèi)存中加載,但由于內(nèi)存的讀寫速度與CPU不在一個級別,這就使得CPU的性能受到內(nèi)存讀寫效率的制約而降低。由此設(shè)計者們開始思考,在CPU流水線指令設(shè)計理念的基礎(chǔ)上,CPU的執(zhí)行效率是否還有提升的空間。

通過觀察發(fā)現(xiàn),CPU每次執(zhí)行指令時用到的數(shù)據(jù),其前后相鄰的數(shù)據(jù)有很大概率也會被用到。例如下面這段循環(huán)代碼,每次輸出元素后都會訪問其后方的元素,因此設(shè)計者開始考慮在CPU上增加一層緩存,通過提前預(yù)讀數(shù)據(jù)來提升CPU運算效率,從而避免因等待內(nèi)存讀取而產(chǎn)生的阻塞問題:

for (int i = 0; i < 10; i++) {
            System.out.println(list.get(i));
        }

由此引入了CPU緩存的設(shè)計,也就有了CPU緩存行的概念,即當(dāng)CPU使用到內(nèi)存中的某塊數(shù)據(jù)時,會將這塊內(nèi)存數(shù)據(jù)連同其附近的數(shù)據(jù)一起加載到CPU緩存中:

考慮到CPU中緩存電路采用讀寫速度較高的SRAM電路,耗用的晶體管數(shù)量比較多,現(xiàn)代CPU L1緩存通常為每個核心32KB到64KB,同時緩存對應(yīng)的基本單位默認(rèn)是緩存行,默認(rèn)大小為64字節(jié)。

于是我們就有了這樣一組cpu緩存的粗略設(shè)計:

  • 每個緩存行都有一個內(nèi)存空間記錄緩存的數(shù)據(jù)地址
  • 緩存行專門用無效標(biāo)識記錄當(dāng)前數(shù)據(jù)是否有效,若標(biāo)識為無效則cpu需要從內(nèi)存中讀取數(shù)據(jù)
  • 臟數(shù)據(jù)標(biāo)識說明這個數(shù)據(jù)被cpu修改過,需要刷新到內(nèi)存中
  • 數(shù)據(jù)字段記錄cpu要操作的數(shù)據(jù)信息

2. 緩存加載的算法

有了緩存基礎(chǔ)之后,設(shè)計者們就開始考慮如何從內(nèi)存中高效地加載數(shù)據(jù)并寫入CPU緩存行中。一開始考慮采用遍歷尋址的方式,但這種方式不僅效率低下,還違背了緩存行設(shè)計的初衷,無法實現(xiàn)快速預(yù)讀和使用。

因此設(shè)計者考慮采用數(shù)據(jù)取模地址并寫入的設(shè)計思路,但是問題又來了,如果兩個要寫入的數(shù)據(jù)地址發(fā)生沖突要如何解決?于是設(shè)計者打算將緩存空間分為四塊,也就是四路組相連。在進(jìn)行緩存寫入時,對四個緩存空間都進(jìn)行取模運算,將數(shù)據(jù)寫入有空閑空間的緩存塊中,這樣既能保證寫入效率,又能盡可能減少沖突:

3. 指令與數(shù)據(jù)緩存分離

在CPU內(nèi)部流水線中,如果執(zhí)行指令的電路和讀取數(shù)據(jù)的電路都需要訪問內(nèi)存,而訪問內(nèi)存的地址譯碼器只有一個,這就使得一方必須阻塞等待,導(dǎo)致雙方中必有一方需要阻塞等待,這就是結(jié)構(gòu)冒險:

于是就考慮到一種名為哈佛架構(gòu)的設(shè)計,即將內(nèi)存空間分為指令空間和數(shù)據(jù)空間以避免這種沖突,但是這種做法會導(dǎo)致內(nèi)存失去動態(tài)分配的優(yōu)勢??紤]到當(dāng)前CPU引入了緩存的概念,可以在緩存的基礎(chǔ)上將執(zhí)行指令和數(shù)據(jù)讀取兩個模塊的緩存空間分離,利用CPU緩存讀取來盡可能避免指令和數(shù)據(jù)訪問沖突。當(dāng)然,這種情況在緩存未命中的情況下還是會出現(xiàn)結(jié)構(gòu)冒險:

4. 多級緩存空間

看到引入緩存后的優(yōu)勢,設(shè)計者提出了多級緩存概念。結(jié)合緩存電路和晶體管的制作成本,最終的折中方案為:

  • 一級緩存容量最小,每個CPU獨有一份一級緩存L1-cache,效率最高,CPU訪問數(shù)據(jù)的時間成本只需要2~4個時鐘周期,緩存分為i-cache和d-cache分別存儲指令和數(shù)據(jù)
  • 二級緩存容量稍大,成本相對控制,所以訪問時間表現(xiàn)稍差,大約需要10~20個時鐘周期
  • 三級緩存多核CPU共享,CPU訪問時間大約20~60個時鐘周期
  • 內(nèi)存大約是200~300個時鐘周期

這里補(bǔ)充一下CPU時鐘周期的概念,時鐘周期是CPU主頻的倒數(shù)。例如我們現(xiàn)在有一個CPU的主頻為2GHz,一個時鐘周期的計算過程如下:

時鐘周期=1/主頻

因為:主頻單位為hz即 次/秒
2GHz= 2*10^9 hz
時鐘周期=1/ 2*10^9
   = 0.0000000005次/秒
   = 0.5ns

所以一個一個2GHz的cpu對應(yīng)的時鐘周期大約是0.5ns即0.5ns執(zhí)行一次cpu事件,也就是每秒鐘發(fā)生20億次事件。

5. cpu緩存基本概念

在CPU訪問數(shù)據(jù)的時候,都會優(yōu)先從緩存中獲取數(shù)據(jù),如果沒有找到再去內(nèi)存中讀取,若內(nèi)存中也找不到,則從磁盤中讀取數(shù)據(jù)并加載到CPU CACHE中。

當(dāng)CPU CACHE開始加載數(shù)據(jù)的時候,并不是按需精確讀取一段數(shù)據(jù),而是一小塊一小塊地進(jìn)行數(shù)據(jù)讀取。而這一小塊數(shù)據(jù)就是我們?nèi)粘Kf的CPU Line(緩存行)。

在Linux中執(zhí)行命令cat /sys/devices/system/cpu/cpu0/cache/index0/coherency_line_size,我們就能看到自己CPU L1 Cache對應(yīng)的CPU Line的大小。以筆者服務(wù)器為例,每個緩存行大小為64字節(jié):

這64字節(jié)是什么概念呢?我們都知道一個整型變量是4個字節(jié)。假如我們聲明一個數(shù)組int data[] = new int[32768];,當(dāng)CPU cache載入data[0]時,由于cache line的大小為64字節(jié),也就是說還會有一些空閑的空間沒用到,根據(jù)局部性原理,CPU就會將剩余部分用于存儲data[0]附近的數(shù)據(jù),也就是說載入data[0]時,cache line順手將索引1-15的元素也加載到CPU cache line中。

當(dāng)cache中有內(nèi)存加載的數(shù)據(jù)時,我們怎么知道這個數(shù)據(jù)對應(yīng)的內(nèi)存那塊數(shù)據(jù)呢?

其實CPU早就考慮到這點了,實現(xiàn)方式也很簡單,通過直接映射Cache(Direct Mapped Cache),說白了就是將內(nèi)存地址和CPU cache line做一個映射,我們都知道內(nèi)存的一塊塊數(shù)據(jù)稱為內(nèi)存塊,實現(xiàn)地址映射的方式也很簡單,就是將內(nèi)存塊地址進(jìn)行取模運算后再將存到對應(yīng)的cache line中。

例如:我們有8個cache line以及32個內(nèi)存塊,當(dāng)cache需要載入15號塊時,cache就會將其存到15%8=7,即7號cache line中。

假如映射地址沖突了怎么辦?這個問題也很簡單,針對每個cache line 增加一個Tag標(biāo)記就好了,例如第4個cache line 存儲的是內(nèi)存塊15的數(shù)據(jù),對應(yīng)的第4個cache line,對應(yīng)第4個cache line的緩存空間數(shù)據(jù)結(jié)構(gòu)為:

  • 設(shè)置valid標(biāo)識為1說明當(dāng)前緩存數(shù)據(jù)有效且未過期(緩存數(shù)據(jù)有效,操作系統(tǒng)其他線程未對緩存對應(yīng)的內(nèi)存數(shù)據(jù)做修改)
  • 設(shè)置設(shè)置tag標(biāo)識說明cache line對應(yīng)的內(nèi)存數(shù)據(jù)是內(nèi)存塊15
  • offset告知cache line中對應(yīng)的偏移地址是我們實際要用到數(shù)據(jù),這樣的數(shù)據(jù)用專業(yè)術(shù)語稱為字(word)

基于cache line,當(dāng)cpu需要用到這份數(shù)據(jù)時,就會執(zhí)行如下流程:

  • 基于內(nèi)存地址通過運算定位到cache line
  • cache line無數(shù)據(jù)則從內(nèi)存加載,反之進(jìn)入步驟3
  • 查看valid標(biāo)識為是否為有效,若無效則從內(nèi)存重新加載,若有效進(jìn)入步驟4
  • 查看offset從cache line定位到實際用到的字(word)

三、(實踐)通過CPU的緩存工作機(jī)制編寫高性能代碼

1. 遍歷順序適配CPU緩存加載順序

先看看下面這段代碼,這段代碼按列遍歷二維數(shù)組,在筆者電腦上運行需要291毫秒:

int[][] arr = new int[10000][10000];
long start = System.currentTimeMillis();

// 逐列遍歷數(shù)據(jù)
for (int i = 0; i < 10000; i++) {
    for (int j = 0; j < 10000; j++) {
        arr[j][i] = 0;
    }
}
long end = System.currentTimeMillis();

再看看這段按行遍歷的代碼,在筆者電腦上運行只需要30毫秒:

int[][] arr = new int[10000][10000];
        
long start = System.currentTimeMillis();
//逐行遍歷二維數(shù)據(jù)
for (int i = 0; i < 10000; i++) {
    for (int j = 0; j < 10000; j++) {
        arr[i][j] = 0;
    }
}

long end = System.currentTimeMillis();

System.out.println("耗時:" + (end - start));

讓我們回顧一下CPU cache的原理,由于局部性原理,加載某個數(shù)據(jù)時會加載其附近的數(shù)據(jù),而第一段代碼是按列(縱向)遍歷數(shù)據(jù)的。這意味著CPU CACHE中的數(shù)據(jù)不一定包含for循環(huán)所需的數(shù)據(jù)。 CPU cache只會順序加載其附近的數(shù)據(jù),假如我們訪問arr[0][0],那么它會順序加載arr[0][1]、arr[0][2]、arr[0][3]等。這就導(dǎo)致按列遍歷過程中,只有第一次訪問的列在緩存中,其他列的數(shù)據(jù)都要從內(nèi)存中讀取。這就是為什么第二段代碼的遍歷順序與局部性原理的加載順序一致,所以效率更高。

2. 綁定CPU(設(shè)置cpu親和力)實現(xiàn)多核 CPU 的緩存命中率

現(xiàn)代CPU都是多核心的,進(jìn)程可能在不同CPU核心間來回切換執(zhí)行,這對CPU Cache是不友好的的。雖然L3 Cache是多核心之間共享的,但是L1和L2 Cache都是每個核心獨有的。如果一個進(jìn)程在不同核心間來回切換,各個核心的緩存命中率就會受到影響;相反,如果進(jìn)程都在同一個核心上執(zhí)行,那么其數(shù)據(jù)的L1和L2 Cache的緩存命中率可以得到有效提高。緩存命中率高意味著CPU可以減少訪問內(nèi)存的頻率。

當(dāng)有多個「計算密集型」線程同時執(zhí)行時,為了防止因切換到不同核心而導(dǎo)致緩存命中率下降的問題,我們可以將線程綁定在某一個CPU核心上,這樣性能可以得到非??捎^的提升。

在Linux上提供了sched_setaffinity方法,用于實現(xiàn)將線程綁定到某個CPU核心的功能,就像下面這段代碼,筆者將兩個線程綁定到4號和5號cpu上:

#include <stdio.h>
#include <unistd.h>
#include <time.h>
#include <signal.h>
#include <string.h>

#define __USE_GNU
#include <sched.h>
#include <pthread.h>

int cpu_core_count;

/**
 * 線程函數(shù)1 - 綁定到指定CPU核心并執(zhí)行空循環(huán)
 * @param arg 指向CPU核心編號的指針
 * @return NULL
 */
void *thread_func1(void *arg) {
    cpu_set_t cpu_set_mask;     // CPU核心集合掩碼
    int *cpu_core_id = (int*)arg;  // CPU核心ID

    // 顯示要綁定的CPU核心
    printf("Binding thread 1 to CPU core %d\n", *cpu_core_id);

    // 初始化CPU集合并設(shè)置要綁定的CPU核心
    CPU_ZERO(&cpu_set_mask);              // 清空CPU集合
    CPU_SET(*cpu_core_id, &cpu_set_mask); // 將指定CPU核心添加到集合中

    // 設(shè)置當(dāng)前線程的CPU親和力
    if (sched_setaffinity(0, sizeof(cpu_set_mask), &cpu_set_mask)) {
        printf("Warning: set affinity failed!\n");
    } else {
        // 簡單的無限循環(huán)
        while (1) {
            // 空循環(huán),不執(zhí)行任何操作
        }
    }

    return NULL;
}

/**
 * 線程函數(shù)2 - 綁定到指定CPU核心并執(zhí)行空循環(huán)
 * @param arg 指向CPU核心編號的指針
 * @return NULL
 */
void *thread_func2(void *arg) {
    cpu_set_t cpu_set_mask;     // CPU核心集合掩碼
    int *cpu_core_id = (int*)arg;  // CPU核心ID

    // 顯示要綁定的CPU核心
    printf("Binding thread 2 to CPU core %d\n", *cpu_core_id);

    // 初始化CPU集合并設(shè)置要綁定的CPU核心
    CPU_ZERO(&cpu_set_mask);              // 清空CPU集合
    CPU_SET(*cpu_core_id, &cpu_set_mask); // 將指定CPU核心添加到集合中

    // 設(shè)置當(dāng)前線程的CPU親和力
    if (sched_setaffinity(0, sizeof(cpu_set_mask), &cpu_set_mask) == -1) {
        printf("Warning: set affinity failed!\n");
    } else {
        // 簡單的無限循環(huán)
        while (1) {
            // 空循環(huán),不執(zhí)行任何操作
        }
    }

    return NULL;
}

/**
 * 主函數(shù) - 創(chuàng)建兩個線程并分別綁定到CPU核心4和5
 * @return 0表示正常退出
 */
int main() {
    pthread_t thread1_handle;  // 線程1句柄
    pthread_t thread2_handle;  // 線程2句柄
    int target_cpu_core_4 = 4; // 目標(biāo)CPU核心4
    int target_cpu_core_5 = 5; // 目標(biāo)CPU核心5

    // 獲取系統(tǒng)CPU核心數(shù)量
    cpu_core_count = sysconf(_SC_NPROCESSORS_CONF);

    // 檢查系統(tǒng)是否有足夠的CPU核心
    if (cpu_core_count <= 5) {
        printf("Warning: System has only %d CPU cores, binding to CPU 4 and 5 may fail\n", cpu_core_count);
    }

    // 創(chuàng)建線程并綁定到指定CPU核心
    pthread_create(&thread1_handle, NULL, (void *)thread_func1, &target_cpu_core_4);
    pthread_create(&thread2_handle, NULL, (void *)thread_func2, &target_cpu_core_5);

    // 等待線程結(jié)束
    pthread_join(thread1_handle, NULL);
    pthread_join(thread2_handle, NULL);

    printf("Main thread end\n");

    return 0;
}

編譯啟動后,指定的兩個cpu使用率跑滿了:

當(dāng)然,對應(yīng)java語言也支持這一點,只是在高并發(fā)架構(gòu)的今天,這種手段帶來的收益遠(yuǎn)不如其他架構(gòu)層面的優(yōu)化,所以筆者就不多做贅述了,感興趣的讀者可以查閱這篇文章:http://www.enmalvi.com/2024/06/27/java-affinity/

四、小結(jié)

本文從計算機(jī)體系結(jié)構(gòu)的發(fā)展歷程作為切入點,深入介紹了CPU發(fā)展初期面臨的性能瓶頸以及緩存技術(shù)的引入?;诔绦驁?zhí)行的局部性特點,提出了局部性原理和緩存預(yù)加載思想。同時針對結(jié)構(gòu)冒險問題,提出了指令和數(shù)據(jù)緩存分離的設(shè)計理念。

文章還詳細(xì)闡述了多級緩存架構(gòu)、緩存映射策略等核心技術(shù),并通過實際代碼示例展示了如何編寫緩存友好型代碼,包括合理的數(shù)據(jù)遍歷順序和條件判斷優(yōu)化等最佳實踐。

此外,本文還介紹了多核CPU環(huán)境下通過線程綁定技術(shù)提升緩存命中率的方法,為優(yōu)化程序性能提供了實用的指導(dǎo)。希望本文的內(nèi)容能幫助您更好地理解和應(yīng)用CPU緩存技術(shù)。

責(zé)任編輯:趙寧寧 來源: 寫代碼的SharkChili
相關(guān)推薦

2025-01-13 13:00:00

Go網(wǎng)絡(luò)框架nbio

2017-05-26 09:50:19

PythonGIL線程安全

2020-12-04 11:40:53

Linux

2024-08-12 08:43:09

2024-03-20 08:00:00

軟件開發(fā)Java編程語言

2023-07-12 08:24:19

Java NIO通道

2019-04-08 16:50:33

前端性能監(jiān)控

2012-12-17 13:51:22

Web前端JavaScriptJS

2022-06-22 08:02:11

CPU操作系統(tǒng)Java

2018-01-12 14:37:34

Java代碼實踐

2021-07-22 09:55:28

瀏覽器前端緩存

2019-04-08 10:09:04

CPU緩存高性能

2009-06-24 15:00:39

Javascript代

2014-04-25 09:02:17

LuaLua優(yōu)化Lua代碼

2024-01-11 11:51:51

Rustmap數(shù)據(jù)結(jié)構(gòu)

2016-09-18 10:25:07

CPU分支預(yù)測模型

2023-11-20 08:10:55

處理器CPU緩存

2019-02-12 14:24:14

緩存高并發(fā)網(wǎng)絡(luò)

2019-05-06 14:36:48

CPULinux寄存器

2015-12-17 13:19:29

編寫高性能Swift
點贊
收藏

51CTO技術(shù)棧公眾號

国产日韩欧美黄色| 色欧美日韩亚洲| 国产精品夫妻激情| 精品人妻在线视频| 91在线看黄| 国产精品人人爽人人做我的可爱| 6080国产精品一区二区| 亚洲欧美在线网| 久久精品五月天| 精品亚洲免a| 香蕉影视欧美成人| 国产精品 日韩| 青青草手机视频在线观看| 亚洲精品成a人ⅴ香蕉片| 国产女人水真多18毛片18精品视频| 超在线视频97| www.午夜av| 中文字幕伦理免费在线视频 | 欧美夜福利tv在线| 国产国语老龄妇女a片| av免费在线网站| 国产精品综合在线视频| 欧美美女18p| 在线观看你懂的视频| 最新黄网在线观看| 国产福利一区在线| 欧美激情综合亚洲一二区| 欧美体内she精高潮| 久久综合网导航| 国产盗摄女厕一区二区三区| 欧美日韩成人在线视频| 岛国精品一区二区三区| av免费不卡国产观看| 99久久久久久99| 国产ts一区二区| 人妻aⅴ无码一区二区三区| 日韩一区二区三区在线免费观看| 日本一区二区在线不卡| 国产在线播放不卡| 免费在线观看av网址| 爱高潮www亚洲精品| 岛国精品视频在线播放| 日本一区二区免费看| 亚洲综合精品在线| 欧美日韩一区二区国产| 日韩av在线不卡| 国产福利影院在线观看| 成人在线免费看片| 99久久精品免费精品国产| 青青草一区二区| 欧美美女性生活视频| 欧美高清一级片| 精品国产精品三级精品av网址| 日韩av一区二区三区在线观看| 91麻豆国产在线| av成人黄色| www高清在线视频日韩欧美| 国产欧美视频一区| 成人免费福利| 亚洲国产一区视频| 日本一区二区三区视频免费看| 国产jzjzjz丝袜老师水多| 国产精品婷婷| 久久天天躁狠狠躁夜夜爽蜜月| 亚洲少妇18p| 欧美成人毛片| 欧美性xxxxxxx| 欧美少妇一级片| 色在线免费视频| 激情五月播播久久久精品| 97精品在线观看| 女人18毛片毛片毛片毛片区二 | 日韩一区二区在线免费观看| 97xxxxx| free性欧美hd另类精品| 久久精品一区二区三区不卡牛牛| 成人精品视频久久久久| 区一区二在线观看| 激情久久五月| 久久亚洲欧美日韩精品专区| 美女爆乳18禁www久久久久久| 77成人影视| 在线不卡欧美精品一区二区三区| 337p粉嫩大胆噜噜噜鲁| 欧美v亚洲v| 亚洲私人影院在线观看| 五月婷婷一区| 内衣办公室在线| 不卡区在线中文字幕| 亚洲xxxx视频| 国产免费无遮挡| 蜜臀av性久久久久av蜜臀妖精| 欧美专区国产专区| 日韩精品视频免费看| 精品69视频一区二区三区Q| 另类天堂视频在线观看| 激情高潮到大叫狂喷水| 成人在线免费视频观看| 亚洲色图色老头| 波多野结衣先锋影音| 大奶在线精品| 日韩一二三区视频| 日韩a一级欧美一级| gogo大尺度成人免费视频| 欧美日韩久久久| 国产精品久久a| 成人看片毛片免费播放器| 在线视频国内一区二区| 欧美成人免费高清视频| 欧美国产大片| 欧洲国产伦久久久久久久| 黄色片视频在线播放| 亚洲欧洲高清| 日本久久电影网| 欧美日韩在线免费播放| jvid一区二区三区| 精品视频在线视频| 久久6免费视频| 日韩欧洲国产| 亚洲国产欧美久久| 国产黄色三级网站| 国产精品嫩模av在线| 国产亚洲精品久久久久久| 亚洲av毛片基地| 99久久99久久精品国产片桃花| 久久亚洲欧美日韩精品专区| 国产午夜精品无码| 香蕉精品999视频一区二区 | 波多野结衣激情| 超碰在线caoporen| 亚洲图片一区二区| 日韩avxxx| 亚洲ww精品| 精品欧美一区二区在线观看| 在线免费观看污视频| 狠狠操综合网| 久久久国产精品视频| 久热这里只有精品在线| 性色av一区二区怡红| 国产精品视频永久免费播放| 国产精品亚洲欧美在线播放| 成人午夜电影网站| 欧美日韩在线观看一区二区三区| 最新97超碰在线| 亚洲永久精品国产| 久久久免费视频网站| 日韩精品第二页| 亚洲丁香婷深爱综合| 中文字幕一区二区三区人妻| 欧美激情电影| 97婷婷涩涩精品一区| 这里只有精品免费视频| 国产精品资源在线观看| 久久国产精品亚洲va麻豆| 成人影视在线播放| 亚洲一区二区欧美| 99视频在线视频| 高清日韩欧美| 日韩中文字幕视频| 精品91久久久| 久久99国产精品麻豆| 精品乱码一区二区三区| 免费网站看v片在线a| 欧美视频13p| 欧美在线a视频| 国产精品一区二区三区av麻| 久久99亚洲精品| 综合久久中文字幕| 99久久国产综合精品色伊 | 在线免费观看的av网站| 亚洲国产精品久久久久婷婷884 | 日韩国产小视频| 电影久久久久久| 欧美精品一区二区不卡| 国产大屁股喷水视频在线观看| 亚洲国产免费| 亚洲一区二区三区乱码aⅴ蜜桃女| 九色在线播放| 午夜精品123| 亚洲妇女无套内射精| 色欧美自拍视频| 国产成人涩涩涩视频在线观看 | 成人sese在线| 日本一道在线观看| 日本成人在线网站| 在线看日韩欧美| 亚洲欧美一区二区三区在线观看| 成熟亚洲日本毛茸茸凸凹| 日本特级黄色大片| 成人av集中营| 国产一区二区三区视频免费| 亚洲GV成人无码久久精品| 成人18视频在线播放| 亚洲精品天堂成人片av在线播放| 亚洲国产91视频| 色av吧综合网| 亚洲香蕉在线视频| 亚洲国产精品高清| 亚洲成人av免费看| 少妇精品久久久一区二区| 国产91ⅴ在线精品免费观看| 五月婷婷丁香网| 香蕉成人伊视频在线观看| 国产精品嫩草69影院| 亚洲手机视频| 激情小说综合网| 免费成人在线电影| 亚洲精品小视频| 五月婷婷激情视频| 国产偷国产偷精品高清尤物| 黄色片在线免费| 精品国产一区二区三区小蝌蚪| 国产成人精品优优av| 久草视频在线看| 欧美在线一二三| 国产91在线播放九色| 狠狠色丁香久久婷婷综| 一级黄色录像免费看| 欧美日韩黄色| 97精品免费视频| 欧美另类自拍| 欧美日韩在线播| 日韩一区二区不卡视频| 国产69精品一区二区亚洲孕妇| 免费视频爱爱太爽了| 任我爽精品视频在线播放| 国产成人精品电影| 午夜激情视频在线| 欧美一区二区三区在线视频| 免费在线观看日韩| 99麻豆久久久国产精品免费| 国产裸体免费无遮挡| 婷婷中文字幕一区| 国产美女99p| 玛雅亚洲电影| 久久亚洲精品小早川怜子66| 性欧美8khd高清极品| 欧美午夜精品久久久久久人妖| 久久婷婷五月综合| 国产精品一卡二| 97国产精东麻豆人妻电影 | 自拍另类欧美| 懂色av一区二区| 国产精品美女久久| 欧美黑人猛交| 夜夜嗨av一区二区三区免费区 | 亚洲三区四区| av一级亚洲| 国产精品视频久久| 91九色在线看| 日韩专区在线观看| 天堂资源中文在线| 欧美久久免费观看| 你懂的国产在线| 亚洲精品视频一区二区| 色哟哟精品观看| 成人黄色综合网站| 久热精品在线播放| 亚洲视频成人| 国产在线视频综合| 欧美色女视频| 久久国产精品久久| 亚洲一级大片| 成人www视频在线观看| 悠悠资源网亚洲青| 欧美极品少妇xxxxⅹ免费视频| 国产美女性感在线观看懂色av | 国内精品免费视频| 日韩成人av影视| 男女视频网站在线观看| 91精品亚洲| 亚洲v欧美v另类v综合v日韩v| xxxx日韩| 97se国产在线视频| 国产精品伦一区二区| 国产91精品高潮白浆喷水| 四季久久免费一区二区三区四区| 中文字幕亚洲在线| 久久精品国产亚洲a∨麻豆| 亚洲成人精品在线| 国产99久久九九精品无码免费| 欧美军同video69gay| 国产精品久久久久久久久夜色| 精品久久香蕉国产线看观看亚洲 | 伊人青青综合网| 亚洲 国产 欧美一区| 要久久电视剧全集免费| 久久av一区二区| 国产一级成人av| 国产成人av一区二区三区| 91精品国产自产观看在线| 国产精品视频网| a成人v在线| 91精品国产自产在线老师啪| 天然素人一区二区视频| 日韩av毛片网| 电影一区二区三区| 欧美在线视频在线播放完整版免费观看| 久久大胆人体| 久久久久亚洲精品国产| 国模雨婷捆绑高清在线| 久久久久久久久久国产| 超免费在线视频| 久久久噜噜噜久久| freexxx性亚洲精品| 2024亚洲男人天堂| 中文不卡1区2区3区| 国产精品成人播放| 国产精品伊人| 91欧美激情另类亚洲| 国产美女视频一区二区| 999热视频| 精品综合久久88少妇激情| 麻豆成人av| 精品日韩在线| 在线观看国产一区| 亚洲最大黄网| www.xxx麻豆| 国产日韩欧美三区| 精品少妇无遮挡毛片| 久久国产精品一区二区| 亚洲无在线观看| 国产99久久久国产精品潘金网站| 天天躁日日躁狠狠躁免费麻豆| gogo大胆日本视频一区| 亚洲图片另类小说| 国产精品国产三级国产aⅴ入口| 日本妇女毛茸茸| 亚洲高清久久久| 天干夜夜爽爽日日日日| 欧美日韩美少妇| 亚洲欧美黄色片| 亚洲欧美日韩成人| 麻豆影视在线观看_| 久久久久久中文字幕| 日韩电影网站| 91麻豆桃色免费看| 欧美大奶一区二区| 亚洲人成人77777线观看| 欧美人成网站| aa在线免费观看| 狠狠色丁香久久婷婷综合_中| 日本天堂在线播放| 国产日产欧美一区| 国内偷拍精品视频| 日韩欧美中文在线| 国产精品午夜福利| 亚洲欧美国产日韩中文字幕| 黄网站免费在线播放| 91超碰caoporn97人人| 色狠狠一区二区三区| 久久国产手机看片| 围产精品久久久久久久| 日本三级免费观看| 国产高清无密码一区二区三区| 精品人妻无码一区| 亚洲国产aⅴ成人精品无吗| 中文文字幕一区二区三三| 精品1区2区在线观看| 91在线看黄| 91精品成人久久| 免费看日产一区二区三区| 欧美日韩一区在线观看视频| 国内精品嫩模av私拍在线观看| 欧美精品性生活| 26uuu精品一区二区三区四区在线 26uuu精品一区二区在线观看 | 日本成人看片网址| 欧美美女在线观看| 成人av在线播放观看| 青青草97国产精品免费观看无弹窗版 | 精品88久久久久88久久久| 97超碰人人在线| 亚州国产精品久久久| 99精品美女视频在线观看热舞| 欧美综合77777色婷婷| 在线欧美福利| 91视频免费入口| 中文字幕一区二区三| 婷婷激情五月综合| 亚洲乱亚洲乱妇无码| av有码在线观看| 成人欧美一区二区三区视频xxx | 99久久这里有精品| 午夜精品福利一区二区| 久久激情一区| 黄色性生活一级片| 亚洲图片欧美色图| 午夜精品久久久久久久96蜜桃| 久久久国产视频91| 少妇精品视频在线观看| 污视频在线免费观看一区二区三区| 亚洲一区二区毛片| 视频免费在线观看| 亚洲一级电影视频| 乱色精品无码一区二区国产盗| 欧美高清激情视频| 亚洲小说春色综合另类电影| 天堂8在线天堂资源bt| 国产成人欧美日韩在线电影| 精国产品一区二区三区a片|