精品欧美一区二区三区在线观看 _久久久久国色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ù)棧公眾號

国产一区日韩| 3d欧美精品动漫xxxx无尽| 成人中文字幕电影| 欧洲成人免费视频| 一本色道久久88| 成功精品影院| 欧美吞精做爰啪啪高潮| 福利在线一区二区| 波多野结衣一区二区| 韩国午夜理伦三级不卡影院| 2019中文字幕免费视频| 国产suv精品一区二区68| 精品久久ai电影| 欧美日韩精品一区视频| 成 年 人 黄 色 大 片大 全| av在线第一页| 91免费视频网| 成人9ⅰ免费影视网站| 黄色网址中文字幕| 亚洲欧洲视频| 久久手机免费视频| 人妻一区二区视频| 久久资源综合| 欧美一区二区大片| 一区二区xxx| 色一区二区三区| 亚洲蜜臀av乱码久久精品| 日本午夜精品一区二区三区| 成人午夜视频一区二区播放| 国精产品一区一区三区mba视频| 欧美在线亚洲在线| 国产一级二级三级视频| 欧美gvvideo网站| 国产亚洲精品综合一区91| 免费观看一区二区三区| 91精品一久久香蕉国产线看观看| 91福利国产精品| 男人日女人逼逼| 免费污视频在线观看| 亚洲欧美自拍偷拍| 亚洲国产婷婷香蕉久久久久久99| 免费人成黄页在线观看忧物| 91日韩精品一区| 国产精品亚洲综合| 亚洲老妇色熟女老太| 国模娜娜一区二区三区| 国产欧美一区二区| 亚洲一区二区三区高清视频| 蜜臀a∨国产成人精品| 国产精品毛片a∨一区二区三区|国| 日本一区二区三区免费视频| 日韩视频三区| 77777亚洲午夜久久多人| 欧美亚洲天堂网| 在线播放一区| 97免费视频在线| 日本熟妇毛耸耸xxxxxx| 国产精品毛片| 欧美整片在线观看| 狠狠人妻久久久久久综合| 毛片一区二区| 国产精品黄视频| 姑娘第5集在线观看免费好剧| 免费成人在线观看视频| 国产有码在线一区二区视频| 91在线视频国产| 国产在线一区二区综合免费视频| 114国产精品久久免费观看| 精品毛片一区二区三区| 成人免费毛片片v| 久久久久资源| 成人资源www网在线最新版| 国产精品色眯眯| 成人免费看片视频在线观看| 男女羞羞视频在线观看| 欧美小视频在线| 波多结衣在线观看| 天堂va欧美ⅴa亚洲va一国产| 亚洲成人av片在线观看| 波多野结衣av在线免费观看| 日韩中文欧美| 欧美黑人性视频| 亚洲GV成人无码久久精品| 日本视频一区二区三区| 国产精品欧美一区二区三区奶水 | 久久精品亚洲欧美日韩精品中文字幕| 久热精品视频在线观看一区| 日本熟妇色xxxxx日本免费看| 丝袜亚洲另类欧美| 92看片淫黄大片看国产片| 天天综合网天天综合| 欧美激情综合五月色丁香小说| 日本三日本三级少妇三级66| 黄色在线观看www| 欧美吞精做爰啪啪高潮| 精品少妇人妻av一区二区三区| 综合色就爱涩涩涩综合婷婷| 伦理中文字幕亚洲| 亚洲精品中文字幕乱码三区91| 极品销魂美女一区二区三区| 蜜桃传媒一区二区| av免费在线观看网站| 欧美性猛交xxxx富婆| 无码国产精品一区二区高潮| 国产探花一区在线观看| 欧美夫妻性生活视频| www.久久视频| 99精品久久久久久| 婷婷视频在线播放| 成人性生活av| 精品国产乱码久久久久久影片| 黄色片在线观看免费| 亚洲三级观看| 亚洲va国产va天堂va久久| 你懂的免费在线观看| 亚洲资源中文字幕| 激情五月婷婷基地| 欧美日韩xxxx| 国产+人+亚洲| 国产深喉视频一区二区| 国产日本欧美一区二区| 欧美色图色综合| 成人久久网站| 亚洲色图国产精品| 日本少妇性高潮| 国产精品系列在线播放| 一区二区三区在线观看www| 日韩新的三级电影| 日韩av在线资源| 国产精彩视频在线观看| 国产综合色产在线精品 | 这里只有精品在线| 国产精品亚发布| 国内在线精品| 第一福利永久视频精品| 性活交片大全免费看| 这里只有精品在线| 亚洲aa中文字幕| 欧美成人三区| 欧美人妖巨大在线| www中文在线| 精品综合免费视频观看| 亚洲高清在线观看一区| 久久久人成影片一区二区三区在哪下载 | 国产精品久久久久一区| 依人在线免费视频| 成人在线免费小视频| 国产精品久久久久久久久免费| 男人天堂亚洲二区| 色成人在线视频| 欧美做受高潮6| 日本午夜精品一区二区三区电影 | 成人在线播放av| 麻豆影视在线观看_| 欧美电影在线免费观看| 一区二区三区四区五区| 国产一区 二区 三区一级| 在线无限看免费粉色视频| 外国成人毛片| 欧美成人在线影院| 亚洲国产精品久久久久久久 | 农民人伦一区二区三区| 久久久久97| 日本精品性网站在线观看| 九色国产在线观看| 欧美日韩高清在线| 动漫性做爰视频| 成人黄色大片在线观看| 欧美性久久久久| 成人羞羞在线观看网站| 成人激情视频在线观看| 国模私拍视频在线播放| 亚洲精品黄网在线观看| 无码日韩精品一区二区| 国产精品美女久久久久久久久久久| 天天干天天玩天天操| 欧美va亚洲va日韩∨a综合色| 国产午夜精品在线| 日本韩国欧美| 两个人的视频www国产精品| 亚洲爱情岛论坛永久| 欧美日韩综合视频| 二区三区四区视频| 成人夜色视频网站在线观看| 成年人免费大片| 婷婷色综合网| 久久久久久久久久久久久久一区| 国产一区一一区高清不卡| 超薄丝袜一区二区| 三区在线观看| 日韩一级在线观看| 日本在线播放视频| 亚洲天堂2014| 六月婷婷七月丁香| 国产精品99久| 黄色免费网址大全| 国产精品www.| 亚洲午夜精品久久久久久浪潮| 久久悠悠精品综合网| 国产在线观看精品| 永久免费毛片在线播放| 久久影院资源网| 全部免费毛片在线播放网站| 日韩一区二区在线观看视频| 久久青青草原亚洲av无码麻豆| 亚洲免费在线观看| 国产中年熟女高潮大集合| 国产99久久久国产精品免费看| 青青草av网站| 99精品视频免费观看视频| youjizz.com亚洲| 精品中文字幕一区二区三区av| 97超级在线观看免费高清完整版电视剧| 这里有精品可以观看| 久久这里只有精品99| 成人福利在线| 国产视频亚洲精品| 俄罗斯嫩小性bbwbbw| 欧美猛男超大videosgay| www.色国产| 亚洲成av人片在线| 亚洲av鲁丝一区二区三区| 国产精品五月天| 97人妻精品一区二区免费| 播五月开心婷婷综合| 日韩高清在线一区二区| 久久精品国产成人一区二区三区 | 亚洲优女在线| 久久久中文字幕| 亚洲精品天堂| 久久中文字幕国产| 快射视频在线观看| 最近2019年日本中文免费字幕| 久久久久久青草| 亚洲精品视频网上网址在线观看| 天堂成人在线视频| 精品久久久久av影院| 精品免费久久久| 欧美一级理论片| 国产乱人乱偷精品视频| 欧美日韩国产高清一区二区三区| 久久久久精彩视频| 在线观看一区日韩| 波多野结衣视频网址| 色综合久久88色综合天天免费| 国产一级片毛片| 欧美天堂在线观看| 69国产精品视频免费观看| 精品动漫一区二区| 日韩一区二区视频在线| 精品高清一区二区三区| yjizz国产| 在线中文字幕一区二区| 成人黄色片在线观看 | 亚洲伦理在线观看| 精品91自产拍在线观看一区| 丰满少妇在线观看bd| 亚洲成人999| 欧美扣逼视频| 中文字幕久久亚洲| 国产不卡在线| 欧美激情在线观看视频| av漫画网站在线观看| 日韩美女激情视频| 国产综合色激情| 91九色在线观看| 欧美综合自拍| 午夜精品区一区二区三| 图片区亚洲欧美小说区| 精品人妻大屁股白浆无码| 亚洲综合另类| 在线观看免费黄网站| 国产精品一区二区无线| 国产一线在线观看| 久久久久国产精品麻豆ai换脸| 国产馆在线观看| 亚洲综合一区二区三区| 欧美h在线观看| 欧美美女喷水视频| 高清一区二区三区四区| 国产亚洲精品91在线| 成人在线网址| 91黄色8090| 成人亚洲视频| av色综合网| 免费观看不卡av| 超级碰在线观看| 亚欧成人精品| 色男人天堂av| 久久久久久免费| 久久国产在线视频| 91豆麻精品91久久久久久| 99免费在线视频| 亚洲图片欧美午夜| 丝袜美女在线观看| 国产激情久久久| 97超碰成人| 亚洲欧洲日夜超级视频| 亚洲图片在线| 中文字幕国产高清| 久久蜜桃一区二区| 久久久久久久久久综合| 在线亚洲人成电影网站色www| 亚洲AV无码精品色毛片浪潮| 在线观看久久av| 交100部在线观看| 成人精品久久久| 亚洲瘦老头同性70tv| 国产欧美自拍视频| 日韩和欧美的一区| 男男做爰猛烈叫床爽爽小说| 综合在线观看色| 波多野结衣视频在线看| 日韩av网站在线| 超黄网站在线观看| 成人激情免费在线| 欧美美女一区| 欧美a在线视频| 成人aa视频在线观看| 九九热最新地址| 欧美精品v国产精品v日韩精品 | 欧美激情一二三区| 日韩av一区二区在线播放| 欧美一级精品大片| 视频一区二区三区不卡| 国产精品美女av| 伊人久久大香线蕉| 18禁网站免费无遮挡无码中文| 国产一区不卡精品| 三上悠亚在线观看视频| 在线一区二区视频| 国产在线黄色| 欧美在线一区二区三区四| 久久亚洲道色| 国产综合中文字幕| 成人性生交大片免费看中文| 日本天堂中文字幕| 日韩一区国产二区欧美三区| 久cao在线| 亚洲aaa激情| 欧美 日韩 国产精品免费观看| www.51色.com| 亚洲精品国产视频| 国产999久久久| 欧美人与物videos| 6080亚洲理论片在线观看| 欧美少妇在线观看| 国产suv精品一区二区6| 欧美极品aaaaabbbbb| 精品奇米国产一区二区三区| 日本在线观看高清完整版| 99se婷婷在线视频观看| 国产一区二区三区四区三区四| 不许穿内裤随时挨c调教h苏绵| 亚洲一区二区三区自拍| 人妻一区二区三区四区| 91精品国产九九九久久久亚洲| 香蕉久久夜色精品国产更新时间| heyzo国产| 久久精品日韩一区二区三区| 探花国产精品一区二区| 日韩一区二区三区国产| 国产精品99久久免费| 成人在线播放网址| 99久久精品国产导航| 成年人av网站| 日韩中文在线观看| 日韩精品免费视频一区二区三区 | 午夜欧美激情| 欧美在线播放一区| 狠狠色狠狠色综合系列| 欧美交换国产一区内射| 精品五月天久久| 精品欧美日韩精品| 特色特色大片在线| www.亚洲精品| 精人妻无码一区二区三区| 日韩在线观看av| 老司机成人在线| 天天操天天摸天天爽| 亚洲精品中文在线影院| 婷婷综合激情网| 国产精品中文字幕久久久| 欧美精品九九| 色欲av无码一区二区三区| 在线成人av影院| heyzo在线| 视频一区二区在线| 高清成人免费视频| 黄色网址中文字幕| 欧美国产日韩一区二区在线观看 | 91成人app| 青青青免费在线| 国产精品福利影院| 日批视频在线播放| 国产日韩欧美在线播放| 亚洲一区久久| 99久久99久久精品国产| 亚洲精品色婷婷福利天堂| 一级欧美视频|