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

9個提高代碼運行效率的小技巧你知道幾個?

系統 Linux
在程序開發和優化的過程中,我們必須考慮代碼使用的方式,以及影響它的關鍵因素。通常,我們必須在程序的簡潔性與它的運行速度之間做出權衡。今天我們就來聊一聊如何優化程序的性能。

[[380880]]

我們寫程序的目的就是使它在任何情況下都可以穩定工作。一個運行的很快但是結果錯誤的程序并沒有任何用處。在程序開發和優化的過程中,我們必須考慮代碼使用的方式,以及影響它的關鍵因素。通常,我們必須在程序的簡潔性與它的運行速度之間做出權衡。今天我們就來聊一聊如何優化程序的性能。

  •  1. 減小程序計算量
    •  1.1 示例代碼
    •  1.2 分析代碼
    •  1.3 改進代碼
  •  2. 提取代碼中的公共部分
    •  2.1 示例代碼
    •  2.2 分析代碼
    •  2.3 改進代碼
  •  3. 消除循環中低效代碼
    •  3.1 示例代碼
    •  3.2 分析代碼
    •  3.3 改進代碼
  •  4. 消除不必要的內存引用
    •  4.1 示例代碼
    •  4.2 分析代碼
    •  4.3 改進代碼
  • 5.  減小不必要的調用
    •  5.1 示例代碼
    •  5.2 分析代碼
    •  5.3 改進代碼
  •  6. 循環展開
    •  6.1 示例代碼
    •  6.2 分析代碼
    •  6.3 改進代碼
  •  7. 累計變量,多路并行
    •  7.1 示例代碼
    •  7.2 分析代碼
    •  7.3 改進代碼
  •  8. 重新結合變換
    •  8.1 示例代碼
    •  8.2 分析代碼
    •  8.3 改進代碼
  • 9 條件傳送風格的代碼
    •  9.1 示例代碼
    •  9.2 分析代碼
    •  9.3 改進代碼
  •  10. 總結

1. 減小程序計算量

1.1 示例代碼 

  1. for (i = 0; i < n; i++) {  
  2.   int nni = n*i;  
  3.   for (j = 0; j < n; j++)  
  4.     a[ni + j] = b[j];  

1.2 分析代碼

代碼如上所示,外循環每執行一次,我們要進行一次乘法計算。i = 0,ni = 0;i = 1,ni = n;i = 2,ni = 2n。因此,我們可以把乘法換成加法,以n為步長,這樣就減小了外循環的代碼量。

1.3 改進代碼 

  1. int ni = 0 
  2. for (i = 0; i < n; i++) {  
  3.   for (j = 0; j < n; j++)  
  4.     a[ni + j] = b[j];  
  5.   ni += n;         //乘法改加法  

計算機中乘法指令要比加法指令慢得多。

2. 提取代碼中的公共部分

2.1 示例代碼

想象一下,我們有一個圖像,我們把圖像表示為二維數組,數組元素代表像素點。我們想要得到給定像素的東、南、西、北四個鄰居的總和。并求他們的平均值或他們的和。代碼如下所示。 

  1. up =    val[(i-1)*n + j  ];  
  2. down =  val[(i+1)*n + j  ];  
  3. left =  val[i*n     + j-1];  
  4. right = val[i*n     + j+1];  
  5. sum = up + down + left + right; 

2.2 分析代碼

將以上代碼編譯后得到匯編代碼如下所示,注意下3,4,5行,有三個乘以n的乘法運算。我們把上面的up和down展開后會發現四格表達式中都有i*n + j。因此,可以提取出公共部分,再通過加減運算分別得出up、down等的值。 

  1. leaq   1(%rsi), %rax  # i+1  
  2. leaq   -1(%rsi), %r8  # i-1  
  3. imulq  %rcx, %rsi     # i*n  
  4. imulq  %rcx, %rax     # (i+1)*n  
  5. imulq  %rcx, %r8      # (i-1)*n  
  6. addq   %rdx, %rsi     # i*n+j  
  7. addq   %rdx, %rax     # (i+1)*n+j  
  8. addq   %rdx, %r8      # (i-1)*n+j 

2.3 改進代碼 

  1. long iinj = i*n + j;  
  2. up =    val[inj - n];  
  3. down =  val[inj + n];  
  4. left =  val[inj - 1];  
  5. right = val[inj + 1];  
  6. sum = up + down + left + right; 

改進后的代碼的匯編如下所示。編譯后只有一個乘法。減少了6個時鐘周期(一個乘法周期大約為3個時鐘周期)。 

  1. imulq %rcx, %rsi  # i*n  
  2. addq %rdx, %rsi  # i*n+j  
  3. movq %rsi, %rax  # i*n+j  
  4. subq %rcx, %rax  # i*n+j-n  
  5. leaq (%rsi,%rcx), %rcx # i*n+j+n 
  6. ... 

對于GCC編譯器來說,編譯器可以根據不同的優化等級,有不同的優化方式,會自動完成以上的優化操作。下面我們介紹下,那些必須是我們要手動優化的。

3. 消除循環中低效代碼

3.1 示例代碼

程序看起來沒什么問題,一個很平常的大小寫轉換的代碼,但是為什么隨著字符串輸入長度的變長,代碼的執行時間會呈指數式增長呢? 

  1. void lower1(char *s)  
  2.  
  3.   size_t i;  
  4.   for (i = 0; i < strlen(s); i++)  
  5.     if (s[i] >= 'A' && s[i] <= 'Z')  
  6.       s[i] -= ('A' - 'a');  

3.2 分析代碼

那么我們就測試下代碼,輸入一系列字符串。

lower1代碼性能測試

當輸入字符串長度低于100000時,程序運行時間差別不大。但是,隨著字符串長度的增加,程序的運行時間呈指數時增長。

我們把代碼轉換成goto形式看下。 

  1. void lower1(char *s)  
  2.  
  3.    size_t i = 0 
  4.    if (i >= strlen(s))  
  5.      goto done;  
  6.  loop:  
  7.    if (s[i] >= 'A' && s[i] <= 'Z')  
  8.        s[i] -= ('A' - 'a');  
  9.    i++;  
  10.    if (i < strlen(s))  
  11.      goto loop;  
  12.  done:  

以上代碼分為初始化(第3行),測試(第4行),更新(第9,10行)三部分。初始化只會執行一次。但是測試和更新每次都會執行。每進行一次循環,都會對strlen調用一次。

下面我們看下strlen函數的源碼是如何計算字符串長度的。 

  1. size_t strlen(const char *s)  
  2.  
  3.     size_t length = 0 
  4.     while (*s != '\0') {  
  5.  s++;   
  6.  length++;  
  7.     }  
  8.     return length;  

strlen函數計算字符串長度的原理為:遍歷字符串,直到遇到‘\0’才會停止。因此,strlen函數的時間復雜度為O(N)。lower1中,對于長度為N的字符串來說,strlen 的調用次數為N,N-1,N-2 ... 1。對于一個線性時間的函數調用N次,其時間復雜度接近于O(N2)。

3.3 改進代碼

對于循環中出現的這種冗余調用,我們可以將其移動到循環外。將計算結果用于循環中。改進后的代碼如下所示。 

  1. void lower2(char *s)  
  2.  
  3.   size_t i;  
  4.   size_t len = strlen(s);  
  5.   for (i = 0; i < len; i++)  
  6.     if (s[i] >= 'A' && s[i] <= 'Z')  
  7.       s[i] -= ('A' - 'a');  

將兩個函數對比下,如下圖所示。lower2函數的執行時間得到明顯提升。

lower1和lower2代碼效率

4. 消除不必要的內存引用

4.1 示例代碼

以下代碼作用為,計算a數組中每一行所有元素的和存在b[i]中。 

  1. void sum_rows1(double *a, double *b, long n) {  
  2.     long i, j;  
  3.     for (i = 0; i < n; i++) {  
  4.  b[i] = 0;  
  5.  for (j = 0; j < n; j++)  
  6.      b[i] += a[i*n + j];  
  7.     }  

4.2 分析代碼

匯編代碼如下所示。 

  1. # sum_rows1 inner loop  
  2. .L4:  
  3.         movsd   (%rsi,%rax,8), %xmm0 # 從內存中讀取某個值放到%xmm0  
  4.         addsd   (%rdi), %xmm0      # %xmm0 加上某個值 
  5.          movsd   %xmm0, (%rsi,%rax,8) # %xmm0 的值寫回內存,其實就是b[i]  
  6.         addq    $8, %rdi  
  7.         cmpq    %rcx, %rdi  
  8.         jne     .L4 

這意味著每次循環都需要從內存中讀取b[i],然后再把b[i]寫回內存 。b[i] +=  b[i] + a[i*n + j]; 其實每次循環開始的時候,b[i]就是上一次的值。為什么每次都要從內存中讀取出來再寫回呢?

4.3 改進代碼 

  1. /* Sum rows is of n X n matrix a  
  2.    and store in vector b  */  
  3. void sum_rows2(double *a, double *b, long n) {  
  4.     long i, j;  
  5.     for (i = 0; i < n; i++) {  
  6.  double val = 0 
  7.  for (j = 0; j < n; j++)  
  8.      val += a[i*n + j];  
  9.          b[i] = val;  
  10.     }  

匯編如下所示。 

  1. # sum_rows2 inner loop  
  2. .L10:  
  3.         addsd   (%rdi), %xmm0 # FP load + add  
  4.         addq    $8, %rdi  
  5.         cmpq    %rax, %rdi  
  6.         jne     .L10 

改進后的代碼引入了臨時變量來保存中間結果,只有在最后的值計算出來時,才將結果存放到數組或全局變量中。

5.  減小不必要的調用

5.1 示例代碼

為了方便舉例,我們定義一個包含數組和數組長度的結構體,主要是為了防止數組訪問越界,data_t可以是int,long等類型。具體如下所示。 

  1. typedef struct{  
  2.  size_t len;  
  3.  data_t *data;    
  4. } vec; 

vec向量示意圖

get_vec_element函數的作用是遍歷data數組中元素并存儲在val中。 

  1. int get_vec_element (*vec v, size_t idx, data_t *val)  
  2.  
  3.  if (idx >= v->len)  
  4.   return 0;  
  5.  *vval = v->data[idx];  
  6.  return 1;  

我們將以以下代碼為例開始一步步優化程序。 

  1. void combine1(vec_ptr v, data_t *dest)  
  2.     long int i;  
  3.     *dest = NULL 
  4.     for (i = 0; i < vec_length(v); i++) {  
  5.  data_t val;  
  6.  get_vec_element(v, i, &val);  
  7.  *dest = *dest * val;  
  8.     } 
  9.  

5.2 分析代碼

get_vec_element函數的作用是獲取下一個元素,在get_vec_element函數中,每次循環都要與v->len作比較,防止越界。進行邊界檢查是個好習慣,但是每次都進行就會造成效率降低。

5.3 改進代碼

我們可以把求向量長度的代碼移到循環體外,同時抽象數據類型增加一個函數get_vec_start。這個函數返回數組的起始地址。這樣在循環體中就沒有了函數調用,而是直接訪問數組。 

  1. data_t *get_vec_start(vec_ptr v)  
  2.  
  3.  return v->data;  
  4.  
  5. void combine2 (vec_ptr v, data_t *dest)  
  6.  
  7.  long i;  
  8.  long length  = vec_length(v);  
  9.     data_t *data = get_vec_start(v);  
  10.  *dest = NULL 
  11.  for (i=0;i < length;i++)  
  12.  {  
  13.   *dest = *dest * data[i];  
  14.  }  

6. 循環展開

6.1 示例代碼

我們在combine2的代碼上進行改進。

6.2 分析代碼

循環展開是通過增加每次迭代計算的元素的數量,減少循環的迭代次數。

6.3 改進代碼 

  1. void combine3(vec_ptr v, data_t *dest)  
  2.  
  3.     long i;  
  4.     long length = vec_length(v);  
  5.     long limit = length-1;  
  6.     data_t *data = get_vec_start(v);  
  7.     data_t acc = NULL  
  8.     /* 一次循環處理兩個元素 */  
  9.     for (i = 0; i < limit; i+=2) {  
  10.     acc = (acc * data[i]) * data[i+1];  
  11.     }  
  12.     /*     完成剩余數組元素的計算    */  
  13.     for (; i < length; i++) {  
  14.   accacc = acc * data[i];  
  15.     }  
  16.     *dest = acc 

在改進后的代碼中,第一個循環每次處理數組的兩個元素。也就是每次迭代,循環索引i加2,在一次迭代中,對數組元素i和i+1使用合并運算。一般我們稱這種為2×1循環展開,這種變換能減小循環開銷的影響。

注意訪問不要越界,正確設置limit,n個元素,一般設置界限n-1

7. 累計變量,多路并行

7.1 示例代碼

我們在combine3的代碼上進行改進。

7.2 分析代碼

對于一個可結合和可交換的合并運算來說,比如說整數加法或乘法,我們可以通過將一組合并運算分割成兩個或更多的部分,并在最后合并結果來提高性能。

特別注意:不要輕易對浮點數進行結合。浮點數的編碼格式和其他整型數等都不一樣。

7.3 改進代碼 

  1. void combine4(vec_ptr v, data_t *dest)  
  2.  
  3.  long i; 
  4.     long length = vec_length(v);  
  5.     long limit = length-1;  
  6.     data_t *data = get_vec_start(v);  
  7.     data_t acc0 = 0;  
  8.     data_t acc1 = 0   
  9.     /* 循環展開,并維護兩個累計變量 */  
  10.     for (i = 0; i < limit; i+=2) {  
  11.     acc0acc0 = acc0 * data[i];  
  12.     acc1acc1 = acc1 * data[i+1];  
  13.     }  
  14.     /*     完成剩余數組元素的計算    */  
  15.     for (; i < length; i++) {  
  16.         acc0acc0 = acc0 * data[i];  
  17.     }  
  18.     *dest = acc0 * acc1; 

上述代碼用了兩次循環展開,以使每次迭代合并更多的元素,也使用了兩路并行,將索引值為偶數的元素累積在變量acc0中,而索引值為奇數的元素累積在變量acc1中。因此,我們將其稱為”2×2循環展開”。運用2×2循環展開。通過維護多個累積變量,這種方法利用了多個功能單元以及它們的流水線能力

8. 重新結合變換

8.1 示例代碼

我們在combine3的代碼上進行改進。

8.2 分析代碼

到這里其實代碼的性能已經基本接近極限了,就算做再多的循環展開性能提升已經不明顯了。我們需要換個思路,注意下combine3代碼中第12行的代碼,我們可以改變下向量元素合并的順序(浮點數不適用)。重新結合前combine3代碼的關鍵路徑如下圖所示。

combine3代碼的關鍵路徑

8.3 改進代碼 

  1. void combine7(vec_ptr v, data_t *dest)  
  2.  
  3.  long i;  
  4.     long length = vec_length(v);  
  5.     long limit = length-1;  
  6.     data_t *data = get_vec_start(v);  
  7.     data_t acc = IDENT    
  8.     /* Combine 2 elements at a time */  
  9.     for (i = 0; i < limit; i+=2) {  
  10.    accacc = acc * (data[i] * data[i+1]);   }  
  11.     /* Finish any remaining elements */  
  12.     for (; i < length; i++) {  
  13.         accacc = acc * data[i];    }  
  14.     *dest = acc 

重新結合變換能夠減少計算中關鍵路徑上操作的數量,這種方法增加了可以并行執行的操作數量了,更好地利用功能單元的流水線能力得到更好的性能。重新結合后關鍵路徑如下所示。

combine3重新結合后關鍵路徑

9 條件傳送風格的代碼

9.1 示例代碼 

  1. void minmax1(long a[],long b[],long n){  
  2.  long i;  
  3.  for(i = 0;i,n;i++){  
  4.         if(a[i]>b[i]){  
  5.             long t = a[i];  
  6.             a[i] = b[i];  
  7.             b[i] = t; 
  8.         }  
  9.    }  

9.2 分析代碼

現代處理器的流水線性能使得處理器的工作遠遠超前于當前正在執行的指令。處理器中的分支預測在遇到比較指令時會進行預測下一步跳轉到哪里。如果預測錯誤,就要重新回到分支跳轉的原地。分支預測錯誤會嚴重影響程序的執行效率。因此,我們應該編寫讓處理器預測準確率提高的代碼,即使用條件傳送指令。我們用條件操作來計算值,然后用這些值來更新程序狀態,具體如改進后的代碼所示。

9.3 改進代碼 

  1. void minmax2(long a[],long b[],long n){  
  2.  long i;  
  3.  forfor(i = 0;i&lt;n;i++){  
  4.  long min = a[i] < b[i] ? a[i]:b[i];  
  5.  long max = a[i] < b[i] ? b[i]:a[i];  
  6.  a[i] = min;  
  7.  b[i] = max;  
  8.  }  

在原代碼的第4行中,需要對a[i]和b[i]進行比較,再進行下一步操作,這樣的后果是每次都要進行預測。改進后的代碼實現這個函數是計算每個位置i的最大值和最小值,然后將這些值分別賦給a[i]和b[i],而不是進行分支預測。 

本文轉載自微信公眾號「嵌入式與Linux那些事」,可以通過以下二維碼關注。轉載本文請聯系嵌入式與Linux那些事公眾號。

 

責任編輯:龐桂玉 來源: 嵌入式與Linux那些事
相關推薦

2020-04-20 17:43:28

Java代碼優化開發

2020-07-08 17:06:00

Python開發工具

2019-05-16 14:09:03

容器技巧開發

2025-07-15 09:50:29

Python編程技巧圖像處理

2023-11-23 10:21:37

2025-07-28 06:49:48

Python開發圖像處理

2019-05-10 14:50:09

Java代碼技巧

2022-09-06 08:07:24

SQL語句查詢

2022-02-28 10:02:54

Linux技巧命令

2020-09-23 09:20:58

代碼Java字符串

2022-11-16 09:04:36

SQL查詢SELECT

2024-01-16 15:19:29

Python內存

2020-02-23 23:29:07

Python編程開發

2019-07-08 14:45:17

Excel數據分析數據處理

2022-07-18 08:08:16

Go?語言技巧

2021-12-08 23:38:25

Python工具代碼

2021-11-19 16:54:11

Python代碼開發

2019-03-19 14:20:58

Linux在機器學習腳本

2022-09-05 14:17:48

Javascript技巧

2019-11-25 10:20:54

CSS代碼javascript
點贊
收藏

51CTO技術棧公眾號

天堂av资源在线| 精品无码久久久久久久| 国产精品毛片aⅴ一区二区三区| 日韩理论片网站| 国产精品久久国产三级国电话系列| 日韩久久久久久久久| 成人激情免费视频| 精品国精品国产| jizz欧美激情18| 1024在线看片你懂得| 国产女主播视频一区二区| 91在线无精精品一区二区| 毛片在线免费视频| 亚洲成人精品| 国产一区二区三区在线看| 性生活在线视频| 久久久久久久黄色片| 日韩国产欧美| 日韩精品中文字幕在线| 免费国偷自产拍精品视频| 中文字幕在线看片| 亚洲综合免费观看高清完整版在线| 欧美日韩一区二区三区在线观看免 | 日韩高清在线一区二区| 依依综合在线| 亚洲第一成人在线| 成人在线观看www| 91亚洲欧美| 久久精品亚洲麻豆av一区二区 | 色综合久久中文| 欧美成人性战久久| 爽爽爽在线观看| 日韩精品第一| 日本久久电影网| 日本十八禁视频无遮挡| 天堂8中文在线| 亚洲免费观看在线视频| 亚洲一区综合| 亚洲搞黄视频| 国产精品久久久99| 日韩欧美亚洲日产国产| 精品一二三区视频| 91麻豆精品一区二区三区| 国产精品夜夜夜一区二区三区尤| 影音先锋国产在线| 久久国产66| 97超碰国产精品女人人人爽| 久久黄色小视频| 国产一区二区三区四区老人| 色综合久综合久久综合久鬼88| 波兰性xxxxx极品hd| 精品无人区麻豆乱码久久久| 亚洲欧洲国产精品| 成人免费av片| 国产成人高清| 一区二区欧美久久| 国产18无套直看片| 日韩理论电影大全| 色吧影院999| 精品自拍偷拍视频| 欧美日韩成人| 国内精品400部情侣激情| 日本一二三区视频| 午夜在线播放视频欧美| 日本一本a高清免费不卡| 91精品国产高清一区二区三密臀| 午夜一级久久| 国产精品国产亚洲伊人久久| 一区二区视频免费| 国内精品久久久久影院色| 亚洲www在线| 亚洲精品一区二区口爆| 99久久精品国产一区| 精品国产综合区久久久久久| 欧美18xxxxx| 欧美国产综合一区二区| 天天做天天爱天天高潮| 黑人精品视频| 一本到不卡精品视频在线观看| 三年中国国语在线播放免费| 97精品资源在线观看| 日韩欧美一区在线观看| 亚洲黄色免费在线观看| 日韩免费看片| 久久久噜噜噜久久中文字免| 天天操夜夜操视频| 九九国产精品视频| 91中文在线观看| 四季av日韩精品一区| 久久奇米777| 日本成人性视频| 免费高潮视频95在线观看网站| 日本乱人伦一区| 五月天激情播播| 麻豆成人入口| 日韩中文字幕第一页| 久久久全国免费视频| 老司机午夜精品视频在线观看| 国产精品美女久久久久av超清| 国产黄色一区二区| 久久精品这里都是精品| 日韩精品免费一区| japanese23hdxxxx日韩| 日韩欧美国产麻豆| 欧美日韩国产黄色| 亚洲精品社区| 91夜夜揉人人捏人人添红杏| 国产在线观看网站| 香蕉加勒比综合久久| 亚洲黄色小视频在线观看| 成人三级av在线| 日韩一区视频在线| 日韩三级一区二区| 成人av午夜影院| 正在播放91九色| 国产精品迅雷| 精品国产不卡一区二区三区| 国产精品1区2区3区4区| 亚洲主播在线| 俄罗斯精品一区二区| 日本成a人片在线观看| 欧美日韩国产在线播放| 涩多多在线观看| 狠狠操综合网| 欧洲成人免费视频| 天天干天天操av| 亚洲一区在线电影| 波多野结衣电影免费观看| 日韩一区电影| 国产精品99久久久久久久久久久久 | 国产在线视频一区二区三区| 日本一区二区三区免费观看| caoporn视频在线| 精品乱码亚洲一区二区不卡| 国产97免费视频| 久久国产三级精品| 亚洲视频电影| 亚洲国产伊人| 色偷偷av亚洲男人的天堂| 成人午夜精品视频| 国产区在线观看成人精品| 日本老熟妇毛茸茸| 精品视频日韩| 国产乱人伦真实精品视频| 99se视频在线观看| 欧美视频一区二区三区四区| 欧美激情亚洲色图| 欧美a一区二区| 亚洲精品9999| 国产 日韩 欧美| 久久天天躁狠狠躁夜夜av| 91成人一区二区三区| 中文字幕视频一区二区三区久| www.xxx亚洲| 视频在线不卡免费观看| 成人a在线视频| 老司机在线视频二区| 3d成人h动漫网站入口| 农村妇女精品一区二区| 国产成人免费视频一区| 欧美成人高潮一二区在线看| 牲欧美videos精品| 国产精品久久久久久久久免费看 | www.蜜臀av| 亚洲一区av在线| 你懂的在线观看网站| 亚洲专区免费| 亚洲精品一卡二卡三卡四卡| 高清一区二区中文字幕| 国外成人性视频| 黄色片视频在线观看| 欧美日韩一级黄| 亚洲av无码一区二区三区在线| 高潮精品一区videoshd| 欧美色图色综合| 成人一区二区| 99久久自偷自偷国产精品不卡| 嗯啊主人调教在线播放视频| 亚洲色图av在线| 99久久精品国产一区色| 婷婷久久综合九色综合伊人色| xxxx日本免费| 国产一区二区三区免费播放| 国产手机免费视频| 欧美精品久久久久久| 99精品国产高清一区二区| 日本а中文在线天堂| xxxxx成人.com| 亚洲av片一区二区三区| 欧美人狂配大交3d怪物一区| 精品午夜福利视频| 日本一区二区三区国色天香| 伊人影院在线观看视频| 丝袜美腿成人在线| 欧美精品在欧美一区二区| 亚洲人成网亚洲欧洲无码| 成人欧美一区二区三区在线湿哒哒 | 高清在线观看av| 精品国产在天天线2019| 波多野结衣电车痴汉| 亚洲综合男人的天堂| 国产精品久久免费观看| 成人av在线电影| 日本一二三区在线| 日本欧美在线观看| 国产av天堂无码一区二区三区| 久久网站免费观看| 久久久久一区二区| 4438全国亚洲精品观看视频| 国产精品美女呻吟| 忘忧草在线日韩www影院| 欧美日韩爱爱视频| 麻豆网站视频在线观看| 亚洲性视频网站| 涩爱av在线播放一区二区| 日韩亚洲欧美成人一区| 在线免费观看日韩视频| 色综合色综合色综合| 国产亚洲精品成人| 一区二区三区四区五区视频在线观看 | 亚洲国产综合网| 538在线一区二区精品国产| 无码无套少妇毛多18pxxxx| 亚洲国产精品一区二区www| 国产一区二区精彩视频| 中文字幕日本乱码精品影院| av永久免费观看| 久久夜色精品国产欧美乱极品| wwwxx日本| 成人自拍视频在线| 色黄视频免费看| 国产制服丝袜一区| 999久久久精品视频| 韩国三级中文字幕hd久久精品| 黄色成人免费看| 日韩精品电影在线| 99re在线视频免费观看| 久久av最新网址| 北条麻妃69av| 免费在线日韩av| 国产在线青青草| 玖玖在线精品| 啊啊啊国产视频| 免费精品99久久国产综合精品| 成人免费毛片播放| 秋霞成人午夜伦在线观看| 激情综合网俺也去| 免费视频最近日韩| 可以看污的网站| 国产在线不卡一卡二卡三卡四卡| 性欧美在线视频| 国产精品性做久久久久久| 国产精品99精品无码视亚| 国产99久久久国产精品潘金| 日本一级大毛片a一| 成年人国产精品| www.自拍偷拍| 中文av一区二区| 538任你躁在线精品视频网站| 亚洲欧美日韩国产成人精品影院| 免费视频一二三区| 天天操天天综合网| 免费黄色av片| 欧美日韩精品专区| 国产富婆一级全黄大片| 亚洲成色999久久网站| 男人的天堂在线免费视频| 国产一区二区三区久久精品| 日本三级在线播放完整版| 久久91精品国产91久久跳| 国产传媒在线观看| 国产成人午夜视频网址| 高清一区二区中文字幕| 国精产品一区二区| 精品视频亚洲| av片在线免费| 久久久xxx| 黄色a级三级三级三级| 99久久精品情趣| 国产精品理论在线| 亚洲精品国产一区二区三区四区在线| 日韩av男人天堂| 欧美性感一区二区三区| www.我爱av| 亚洲日韩中文字幕在线播放| 成人区精品一区二区不卡| 97视频在线观看播放| 欧美日韩视频网站| 99在线观看视频| 欧美激情在线精品一区二区三区| eeuss中文| 久久九九免费| 性高潮免费视频| 中文字幕一区二区三区在线观看| 黄色激情视频在线观看| 欧美日韩三级一区| 天堂在线资源库| 欧美成人在线免费| 3d性欧美动漫精品xxxx软件| 波多野结衣精品久久| 日韩电影免费在线观看| 欧美在线观看成人| 国产不卡免费视频| 你懂得在线观看| 在线观看日韩高清av| 日本美女一级片| 欧美刺激性大交免费视频| 国产资源一区| 欧美成人免费在线| 在线播放一区| 欧美性受xxxx黒人xyx性爽| 国产清纯美女被跳蛋高潮一区二区久久w | 亚洲超碰精品一区二区| 一级成人免费视频| 亚洲人午夜精品免费| a天堂资源在线| 成人欧美一区二区三区在线观看| 手机亚洲手机国产手机日韩| 国产男女激情视频| 97久久精品人人做人人爽| 久久精品国产av一区二区三区| 欧美日本在线播放| 成年女人的天堂在线| 青青草原成人在线视频| 精品欧美午夜寂寞影院| 成人黄色片免费| 国产在线视视频有精品| 国产美女福利视频| 欧美亚洲国产一区二区三区va| 天堂av中文在线资源库| 午夜精品久久久99热福利| 丁香一区二区| 污污污污污污www网站免费| 国产一区二区久久| 欧美在线视频第一页| 欧美日本国产一区| 1769在线观看| 国产日韩综合一区二区性色av| 成人精品天堂一区二区三区| 波多野结衣天堂| 亚洲国产精品t66y| 这里只有久久精品视频| 一区二区三区日韩在线| 亚洲第一会所001| 手机看片福利永久国产日韩| 日韩av一级电影| 亚洲图片第一页| 欧美精品色一区二区三区| 黄网页在线观看| aa日韩免费精品视频一| 最新亚洲视频| 黄瓜视频污在线观看| 在线一区二区三区| 尤物网在线观看| 亚洲最大福利网站| 国产在线欧美| 国产精品久久无码| 色综合久久天天综合网| www.久久热.com| 亚洲一区二区自拍| 黄色另类av| 香蕉网在线播放| 欧美色成人综合| 在线免费观看的av| 久久99蜜桃综合影院免费观看| 乱码第一页成人| 97精品在线播放| 欧美精品一区二| japanese23hdxxxx日韩| 午夜探花在线观看| www.在线成人| 最近中文字幕在线观看视频| 久热爱精品视频线路一| 福利片一区二区| 日韩中文字幕免费在线 | 亚洲精品午夜国产va久久成人| 亚洲欧美在线免费| 国产精品亚洲欧美日韩一区在线 | 国产精品亚洲人在线观看| 日本三级理论片| 中文字幕精品一区久久久久| 视频二区欧美| 天天操天天爽天天射| 一区二区在线免费观看| 免费人成黄页在线观看忧物| 91精品中文在线| 亚洲伊人观看| 国产精品三区在线观看| 日韩精品高清视频| 国产免费区一区二区三视频免费 | 亚洲性生活视频在线观看| 人人九九精品视频| 亚欧在线免费观看| 亚洲大片免费看| 免费在线午夜视频| 麻豆一区区三区四区产品精品蜜桃| 韩国av一区二区三区在线观看| 久久久久99精品成人片我成大片| 久久影视电视剧免费网站清宫辞电视| 日本三级久久|