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

你可以信任由編譯器優化的代碼嗎?

譯文 精選
開發 開發工具
作為一種工具,編譯器有時很難對當前函數之外的代碼,以及局部變量中沒有保存的值進行推理。本文重點介紹內聯和聚合的標量替換兩種補救性的優化方式。

譯者 | 陳峻

51CTO讀者成長計劃社群招募,咨詢小助手(微信號:TTalkxiaozhuli)

不知您是否了解單指令流多數據流,也就是我們常聽說的SIMD(Single Instruction Multiple Data)?它是采用單個控制器來控制多個處理器,同時對一組數據中的每一個分別執行相同的操作,從而實現空間上的并行性的一種技術。就SIMD的工作原理而言,我們可以將其理解為三個層次:

  • 編譯器具有一定智能,可以自動矢量化(auto-vectorize)所有的代碼。
  • 編譯器自動向量化的能力欠佳,容易受不相關代碼變更的影響,因此開發人員需要手動編寫明確的SIMD指令。
  • 需要重復為每個不同的CPU架構手工編寫SIMD。此時,作為工具的編譯器,可以通過更好的指令和約束,以適合向量化的形式,編寫出可靠的向量化代碼。

在日常工作中,我們的開發場景通常處于第二級和第三級,需要用編譯器來優化模型。下面,我將和您討論靜態語言(如Rust或C++)編譯器優化的一般框架,以及如何將該框架應用于自動矢量化。

1、從編譯器的視角看問題

首先,讓我們來了解編譯器是如何查看代碼的。鑒于有著許多結構上相似之處,我們可以參照WebAssembly規范(https://webassembly.github.io/spec/core/)來了解編譯器在優化方面的核心規范。如下方簡單代碼段所示,一個優化單元往往就是一個函數:

fn sum(xs: &[i32]) -> i32 {
let mut total = 0;
for i in 0..xs.len() {
total = total.wrapping_add(xs[i]);
}
total
}
在一些偽IR(指令寄存器)中,上述代碼表現為:
fn sum return i32 {
param xs_ptr: ptr
param xs_len: size
local total: i32
local i: size = 0
local x: i32
local total: i32 = 0
loop:
branch_if i >= xs_len :ret
load x base=xs_ptr offset=i
add total x
add i 1
goto :loop
ret:
return total
}

此處出現了兩個重要的特征實體:

  • 作為粗略字節數組的程序內存,編譯器往往無法很好地推斷出內存中的內容。而且由于它們是由所有函數共享的,因此不同的函數可能會以不同的方式去解釋內存中的內容。
  • 作為整數形式的局部變量,它們遵循編譯器可推理的數學屬性。

例如,如果編譯器看到了如下循環:

param n: u32
local i: u32 = 0
local total: u32
local tmp
loop:
branch_if i >= n :ret
set tmp i
mul tmp 4
add t tmp
goto :loop
ret:
return total

它可以推斷在每一次循環中,tmp能夠保持i * 4,進而會將其優化為:

param n: u32
local i: u32 = 0
local total: u32
local tmp = 0
loop:
branch_if i >= n :ret
add t tmp
add tmp 4 # replace multiplication with addition
goto :loop
ret:
return total

不過,如果我們進行相同的計算,但所有數字都位于內存中,那么編譯器將很難推斷出轉換的正確性。如果針對n的存儲和total實際是重疊的,而tmp與某些不在當前函數中的數據重疊了,該怎么辦呢?

其實,load和store指令可以作為數學局部變量和內存字節的橋梁。也就是說,load指令在內存中獲取一系列字節,將字節解釋為整數,并將該整數存儲到局部變量中。而store指令的執行操作正好相反。通過將某些內容從內存加載到本地,編譯器可以獲得對其進行精確推理的能力。因此,編譯器無需跟蹤內存的基本內容,只需檢查在特定時間點,從內存進行的加載是否正確即可。可見,編譯器一次只能真正推理一個函數,而且只能推理該函數中的局部變量。

2、將代碼向編譯器推近些

通過為編譯器提供更多的上下文,我們可以實現兩項核心的優化任務:

第一項核心優化是內聯(inlining)。它使用被調用者去代替特定的調用。據此,調用者和被調用者的局部變量都在同一個框架中,編譯器可以一起優化它們。

讓我們看一段Rust代碼:

fn sum(xs: &[i32]) -> i32 {

let mut total = 0;
for i in 0..xs.len() {
total = total.wrapping_add(xs[i]);
}
total
}

其中的表達式xs[i]實際上是一個函數調用。索引函數在訪問數組元素之前,會進行邊界檢查。將其內聯到sum中后,編譯器可以看到其代碼并消除之。畢竟,在內聯之后,函數傾向于處理一般情況,并在特定的調用站點(call-site),使用足夠的約束,來消除各種邊緣情況。

第二項核心優化是聚合的標量替換(scalar replacement of aggregates,SROA)。我們使用load避免對內存進行推理,而是對本地進行推理。

例如,有如下這樣一個函數:

fn permute(xs: &mut Vec<i32>) {
...
}

編譯器會收到一個指向某段內存的指針。由于該內存包含了一個復雜的結構(即:ptr、len、capacity triple),因此它很難推理出該結構的演變。對此,編譯器可以從內存中加載該結構,并使用一堆標量局部變量,來進行替換聚合:

fn permute(xs: &mut Vec<i32>) {
local ptr: ptr
local len: usize
local cap: usize
load ptr xs.ptr
load len xs.len
load cap xs.cap
...
store xs.ptr ptr
store xs.len len
store xs.cap cap
}

如此,編譯器再次獲得了推理能力。雖然與內聯類似,但是SROA主要用于內存,而不是代碼。

3、不可能與可能

使用編譯器模型的主要優勢在于:

  • 在每個函數的基礎上進行優化
  • 可以進行內聯函數的調用
  • 擅長發現局部變量之間的關系,并據此重新排列代碼
  • 能夠對內存進行有限的推理(即,決定何時適合load或store)。

當然,我們需要描述哪些代碼可以被可靠地優化,哪些代碼無法被優化,從而解釋零成本抽象(zero cost abstractions)。針對啟用內聯的情況,編譯器需要知道有哪個函數被實際調用了。如果屬于直接調用,編譯器則會嘗試著與之內聯;如果是間接調用(即:通過函數指針或通過虛函數表進行調用),那么在一般情況下,編譯器將無法與之內聯。對于間接調用而言,編譯器有時也可以推斷指針的值,并對調用進行去虛擬化(de-virtualize)。不過,這往往依賴于在其他地方已實現了成功的優化。

這也就是為什么在Rust中,每個函數都有一個唯一的、大小為零(zero-sized)的類型,而且并沒有運行時(runtime)的表示。它靜態的方式保證了編譯器始終可以內聯到代碼上,以使得抽象的成本為零,畢竟任何優化編譯器都會將其“融化”為零。

當然,更高級別的語言則可能會選擇始終使用函數指針去表示函數。實際上,在許多情況下,它們生成的代碼就等效為可優化的。不過,在源代碼中是不會有任何跡象來表明這是一個可優化的情況(實際指針在編譯時是可知的),還是真正的動態調用狀況。因此,使用Rust就保證了可優化和潛在可優化之間的區別,能夠反映在源語言之中,請參見如下代碼段:

// Compiler is guaranteed to be able to inline call to `f`.
fn call1<F: Fn()>(f: F) {
f()
}
// Compiler _might_ be able to inline call to `f`.
fn call2(f: fn()) {
f()
}

由上述代碼可知,其第一條規則便是使大多數調用可以被靜態解析,以允許內聯。而函數指針和動態調度則會防止內聯。此外,內存中的間接尋址也會給編譯器帶來如下麻煩:

struct Foo {
bar: Bar,
baz: Baz,
}

顯然,上述Foo結構對編譯器是完全透明的。不過,讓我們稍作如下修改:

struct Foo {
bar: Box<Bar>,
baz: Baz,
}

上述結果就不那么明確了。也就是說,被Foo占用的內存一般不會轉移到被Bar占用的內存處。同樣,在許多情況下,鑒于唯一性,編譯器可以通過box進行“不保證”的推理。

如下代碼段展示了map是如何被簽名和定義的。

#[inline]
fn map<B, F>(self, f: F) -> Map<Self, F>
where
Self: Sized,
F: FnMut(Self::Item) -> B,
{
Map::new(self, f)
}

關于內存的另一個重點是,一般而言,編譯器不能改變整體布局。SROA可以將一些數據結構加載到一堆局部變量中,然后可以用“一對指針”代替“一個指針和一個索引”的表示。不過,SROA最終將不得不具體化“一個指針和一個索引”,并將該表示存儲回內存之中。這是因為內存布局是在所有函數之間共享的,因此函數不能單方面地指定更優化的表示。

總之,只要能夠“看到”代碼,編譯器就能夠更擅長推理代碼。因此,請確保大多數調用在編譯時可以實現內聯。

四、SIMD

讓我們將前面討論的、為編譯器提供可優化代碼的通用框架,應用到自動矢量化上。下面是我們優化計算兩個字節片之間最長公共前綴的函數。

use std::iter::zip;
// 650 milliseconds
fn common_prefix(xs: &[u8], ys: &[u8]) -> usize {
let mut result = 0;
for (x, y) in zip(xs, ys) {
if x != y { break; }
result += 1
}
result
}

如果您已經有了自動矢量化的模型,或者已查看了匯編的輸出,那么就會發現一次僅處理一個字節的函數,效率非常慢。我們該如何解決這個問題呢?

SIMD既然可以同時處理多個值,那么我們就希望編譯器能夠同時比較一堆字節。例如,我們通過如下代碼段,先一次性處理16個字節,然后分別處理剩余部分,以便使得結構更加顯式化:

// 450 milliseconds
fn common_prefix(xs: &[u8], ys: &[u8]) -> usize {
let chunk_size = 16;
let mut result = 0;
'outer: for (xs_chunk, ys_chunk) in
zip(xs.chunks_exact(chunk_size), ys.chunks_exact(chunk_size))
{
for (x, y) in zip(xs_chunk, ys_chunk) {
if x != y { break 'outer; }
result += 1
}
}
for (x, y) in zip(&xs[result..], &ys[result..]) {
if x != y { break; }
result += 1
}
result
}

其實,上述代碼在速度上的提升是遠遠不夠的。具體來說,SIMD需要以相同的方式,并行處理塊中的所有值。在上述代碼中,我們用到了一個break。這意味著第n對字節的處理,取決于第n-1對。我們可以通過禁用短路(short-circuiting),來檢查整個字節塊是否匹配。當然,我們并不關心具體哪個特定字節出現了不匹配:

// 80 milliseconds
fn common_prefix3(xs: &[u8], ys: &[u8]) -> usize {
let chunk_size = 16;
let mut result = 0;
for (xs_chunk, ys_chunk) in
zip(xs.chunks_exact(chunk_size), ys.chunks_exact(chunk_size))
{
let mut chunk_equal: bool = true;
for (x, y) in zip(xs_chunk, ys_chunk) {
// NB: &, unlike &&, doesn't short-circuit.
chunk_equal = chunk_equal & (x == y);
}
if !chunk_equal { break; }
result += chunk_size;
}
for (x, y) in zip(&xs[result..], &ys[result..]) {
if x != y { break; }
result += 1
}
result
}

至此,矢量化已成功開始,而且幾乎減少了一個數量級的運行時間。我們現在可以使用迭代器來進行壓縮了。

// 80 milliseconds
fn common_prefix5(xs: &[u8], ys: &[u8]) -> usize {
let chunk_size = 16;
let off =
zip(xs.chunks_exact(chunk_size), ys.chunks_exact(chunk_size))
.take_while(|(xs_chunk, ys_chunk)| xs_chunk == ys_chunk)
.count() * chunk_size;
off + zip(&xs[off..], &ys[off..])
.take_while(|(x, y)| x == y)
.count()
}

顯然,此時的代碼已與我們開始時有了顯著不同。可見,我們不應盲目依賴編譯器的優化,而需要知道在何種情況下進行特定優化,以觸發它們編寫代碼的方式。例如,對于SIMD而言,我們需要根據處理元素塊來表達算法。而且在每個塊中,我們應確保沒有分支,讓所有元素都能以相同的方式處理。

原文鏈接:https://matklad.github.io/2023/04/09/can-you-trust-a-compiler-to-optimize-your-code.html

譯者介紹

陳峻 (Julian Chen),51CTO社區編輯,具有十多年的IT項目實施經驗,善于對內外部資源與風險實施管控,專注傳播網絡與信息安全知識與經驗。


責任編輯:武曉燕 來源: 51CTO技術棧
相關推薦

2023-11-15 17:58:58

C++代碼

2011-05-18 11:06:25

java編譯器

2010-09-16 15:57:25

Java編譯器

2021-10-09 12:08:23

Facebook編譯器機器學習

2022-02-23 13:31:26

RVO編譯器優化

2009-05-05 09:55:10

Javastring對象

2012-04-05 09:13:17

C代碼

2020-11-10 13:42:07

Go編譯器修復

2010-01-13 17:12:26

C++編譯器

2010-01-14 14:55:14

C++編譯器

2022-08-02 08:11:41

監控埋點埋點方式插樁

2010-03-23 11:17:16

Python 動態編譯

2023-03-26 20:39:01

2020-04-02 15:39:51

代碼編譯器前端

2010-10-20 13:43:37

C++編譯器

2022-05-18 09:31:42

編譯器開源代碼生成

2014-05-04 12:51:21

Javascript編譯器

2020-05-13 14:15:25

if-else代碼前端

2010-01-18 10:34:21

C++編譯器

2010-01-21 09:11:38

C++編譯器
點贊
收藏

51CTO技術棧公眾號

日韩精品免费视频人成| 欧美影院天天5g天天爽| 亚洲欧美激情插| 91久久精品一区二区别| 久草视频免费在线播放| 日韩手机在线| 欧美日韩高清在线播放| 精品国偷自产一区二区三区| 日韩大胆人体| 久久国产麻豆精品| 欧美高清视频一区二区| 国产手机在线观看| 日本亚州欧洲精品不卡| 高跟丝袜欧美一区| 99re6这里有精品热视频| 青梅竹马是消防员在线| 国内精品在线播放| 欧美在线国产精品| 欧美日韩黄色网| 久久av免费| 日韩一区二区三区视频在线| 国产视频一区二区三区在线播放| 香蕉成人app免费看片| 久久精品欧美一区二区三区不卡| 91在线观看免费| 亚洲视屏在线观看| 欧美亚洲免费| 欧美寡妇偷汉性猛交| 五月天婷婷丁香网| 秋霞蜜臀av久久电影网免费 | 精品少妇一二三区| 成人系列视频| 亚洲女人天堂成人av在线| 午夜激情视频网| 不卡亚洲精品| 色88888久久久久久影院野外| 日本五级黄色片| 黄网址在线观看| 国产欧美精品区一区二区三区 | 动漫av免费观看| av电影免费在线看| 亚洲欧美怡红院| 天天综合色天天综合色hd| 特级丰满少妇一级aaaa爱毛片| 国内精品久久久久影院一蜜桃| 日本亚洲欧洲色α| 欧美一级视频免费观看| 在线成人av| 久久久久国色av免费观看性色 | 亚洲第一激情av| 四虎免费在线观看视频| 日本在线视频网| 国产精品人成在线观看免费| 日韩在线电影一区| fc2在线中文字幕| 国产调教视频一区| 青青草国产精品| 精品三级久久久久久久电影聊斋| 久久夜色精品国产欧美乱极品| 国内精品**久久毛片app| 日韩性xxxx| 97精品久久久午夜一区二区三区| 国产精品日韩欧美一区二区| 蜜臀av中文字幕| av在线综合网| 免费国产一区| 美国成人毛片| 国产精品美女视频| 99久re热视频精品98| av在线看片| 亚洲一区二区在线观看视频| 免费特级黄色片| 小视频免费在线观看| 色综合久久天天| 成人免费xxxxx在线视频| 91九色综合| 这里是久久伊人| 久久av一区二区三| 欧美日韩一本| 中文在线资源观看视频网站免费不卡| 制服丨自拍丨欧美丨动漫丨| 91精品久久久久久久蜜月| 欧美激情久久久| 女人十八岁毛片| 免费日本视频一区| 亚洲精品女av网站| 婷婷视频在线观看| 欧美国产日韩精品免费观看| 一级特黄妇女高潮| 蜜桃麻豆av在线| 欧美日韩一区高清| 麻豆tv在线观看| 亚洲精品**不卡在线播he| 这里只有精品在线播放| 久久久久99精品成人片毛片| 午夜在线一区| 91在线视频精品| 日韩三级电影网| 一区免费观看视频| 波多野结衣之无限发射| 农村妇女一区二区| 亚洲国产日韩一区| 国产美女高潮视频| 亚洲女人av| 成人欧美在线观看| 国产一区喷水| 91激情在线观看| 97精品国产露脸对白| 亚洲精品一区二区三| 美足av综合网| 欧美色窝79yyyycom| 白丝校花扒腿让我c| 欧美一级精品片在线看| 久久久久久久久中文字幕| 中国a一片一级一片| av男人天堂一区| 国产成人三级视频| 91大神在线观看线路一区| 精品国产青草久久久久福利| 99re6热在线精品视频| 国产日本精品| 超碰97国产在线| 日本中文字幕伦在线观看| 欧美日韩一区二区三区在线免费观看| 免费看的av网站| 成人午夜国产| 欧美中文在线免费| 蜜臀久久99精品久久久| 亚洲丝袜自拍清纯另类| 少妇一级淫免费放| 在线日韩一区| 国产69久久精品成人看| 黑人操亚洲女人| 中文字幕一区在线观看| 日本在线一二三区| 久久最新网址| 日本午夜精品理论片a级appf发布| 黑人精品一区二区| 亚洲影视在线播放| 久久精品五月婷婷| 91 在线视频| 日韩经典一区二区| 欧洲一区二区日韩在线视频观看免费| 国产在线精彩视频| 欧美精品一区二区蜜臀亚洲| 麻豆疯狂做受xxxx高潮视频| 韩国成人精品a∨在线观看| 亚洲高清不卡一区| 性欧美1819sex性高清| 亚洲人午夜色婷婷| 久草视频一区二区| 久久久久久亚洲综合影院红桃| 精品无码一区二区三区爱欲| 日韩免费一级| 欧美日本黄视频| 午夜精品久久久久久久第一页按摩 | 国产精品电影一区二区| 欧美午夜aaaaaa免费视频| 国产一区2区| 国产激情久久久| 欧美日韩在线精品一区二区三区激情综 | 制服丝袜中文字幕一区| 美国一级片在线观看| 狠狠色丁香久久婷婷综合_中| 在线视频不卡一区二区| 国产情侣一区在线| 欧美激情一区二区久久久| 后进极品白嫩翘臀在线视频| 狠狠躁夜夜躁久久躁别揉| 97超碰在线资源| 蜜臀国产一区二区三区在线播放| 亚洲综合av一区| 三级欧美日韩| 668精品在线视频| 免费在线观看一级毛片| 欧美三级中文字幕| 久久久久国产精品夜夜夜夜夜| 高清不卡一区二区在线| aa在线免费观看| 久久大综合网| 国产精品一级久久久| 色戒汤唯在线观看| 中文字幕久久久av一区| av中文字幕免费| 激情成人在线视频| 免费一级做a爰片久久毛片潮| 精品一区精品二区高清| 亚洲国产精品无码av| 精品国产一区二区三区香蕉沈先生| 国产美女久久精品| 黄色大片在线| 尤物九九久久国产精品的分类| 国产女人高潮时对白| 午夜电影一区二区三区| 亚洲色图 激情小说| 国产精品一区在线| 亚洲国产精品久久久久爰色欲| 成人毛片免费看| 97伦理在线四区| 亚洲高清黄色| 九九久久综合网站| 搞黄视频在线观看| 欧美精品一区在线观看| 亚洲日本欧美在线| 无遮挡的视频在线观看| 精品久久久久久久人人人人传媒| 无码人妻精品一区二区三区9厂| 亚洲精品日日夜夜| 91网站免费入口| 国产精品影音先锋| caoporn超碰97| 狠狠入ady亚洲精品| 亚洲v欧美v另类v综合v日韩v| 成人搞黄视频| 成人免费网站在线观看| 成人福利视频| 高清欧美一区二区三区| 麻豆tv入口在线看| 亚洲视频欧洲视频| 五十路在线视频| 欧美一区二区三区系列电影| 欧美一区免费看| 亚洲电影在线免费观看| 欧洲猛交xxxx乱大交3| 国产欧美日韩精品在线| 91av在线免费| 成人污污视频在线观看| 成人av毛片在线观看| 久久久久久久波多野高潮日日| 被灌满精子的波多野结衣| 综合五月婷婷| 欧美少妇一级片| 成人在线免费观看网站| 欧美一区二区三区成人久久片| 秋霞综合在线视频| 国产日韩久久| 国产无遮挡裸体免费久久| 91精品黄色| 国产精品亚洲四区在线观看| 国产日韩欧美视频| 99riav视频一区二区| 日韩av大片免费看| 高清av不卡| 欧美在线播放视频| 亚洲国产福利| 日韩美女视频免费看| 天堂av在线网| 日本精品久久久久影院| 悠悠资源网亚洲青| 欧洲s码亚洲m码精品一区| xx欧美视频| 国产精品久久久久福利| 深夜视频一区二区| 国产精品久久视频| 992tv国产精品成人影院| 国产噜噜噜噜久久久久久久久| 国产极品一区| 91精品久久久久久久久久久| 风韵丰满熟妇啪啪区老熟熟女| 一区二区三区午夜探花| 天天做天天爱天天高潮| 午夜国产欧美理论在线播放 | 国产 xxxx| 99精品久久久久久| 深爱五月激情网| 国产亚洲一区二区在线观看| 日本二区在线观看| 中文字幕亚洲精品在线观看| 久久免费看少妇高潮v片特黄| 亚洲色图在线视频| 久久久久久久福利| 精品成人在线视频| 少妇又紧又色又爽又刺激视频| 欧美美女网站色| 国产肥老妇视频| 日韩av在线影院| av片在线看| 久久综合网hezyo| 国内精彩免费自拍视频在线观看网址| 欧美亚洲日本黄色| 日本久久一区| 国产伦理一区二区三区| 国产传媒欧美日韩成人精品大片| 亚洲精品高清国产一线久久| 在线观看日韩| 久久精品免费一区二区| 看电视剧不卡顿的网站| 中文字幕人妻一区| 国产片一区二区三区| 日韩一区二区不卡视频| 精品久久久久久中文字幕一区奶水| 黄色污污视频软件| 日韩午夜激情视频| 精品电影在线| 色综合久久悠悠| 成人av三级| 97久久夜色精品国产九色| 夜色77av精品影院| 好色先生视频污| 美女久久网站| 麻豆av免费看| 国产精品私人自拍| 日韩精品在线不卡| 欧美日韩国产乱码电影| 五十路在线视频| 久久影院中文字幕| 人人视频精品| 国产精品国模大尺度私拍| 欧美精选一区二区三区| 99色这里只有精品| 国产综合久久久久久鬼色| 双性尿奴穿贞c带憋尿| 尤物视频一区二区| 中文字幕在线网站| 精品一区二区亚洲| 日日夜夜天天综合入口| 狠狠躁天天躁日日躁欧美| 成人毛片一区二区| 精品一区在线看| 美女爆乳18禁www久久久久久| 夜夜精品视频一区二区| 亚洲无码精品在线播放| 亚洲老板91色精品久久| 日本色护士高潮视频在线观看| 国产精品爽爽爽| 欧美精品第一区| 大陆av在线播放| 国产激情一区二区三区桃花岛亚洲| 成人黄色免费网址| 色婷婷一区二区三区四区| 色偷偷在线观看| 欧美激情一级精品国产| 欧洲精品99毛片免费高清观看| 中文字幕精品一区日韩| 日本aⅴ免费视频一区二区三区| 女人被狂躁c到高潮| 疯狂蹂躏欧美一区二区精品| 欧美亚洲精品在线观看| 久久久久久久久网站| 2020国产精品极品色在线观看| 爱爱爱视频网站| 久久激情综合网| 精品国产国产综合精品| 欧美日韩精品一二三区| av亚洲在线| 国产精品一二三视频| 精品久久91| 9久久婷婷国产综合精品性色 | 欧美电影一区二区| 婷婷在线视频观看| 国产美女被下药99| 天天综合网网欲色| 亚洲自拍第三页| 夜夜嗨av一区二区三区中文字幕| 亚洲国产福利视频| 欧美精品久久久久久久久久| 国产精品18hdxxxⅹ在线| 日本国产在线播放| 久久综合丝袜日本网| 一级一片免费看| 最近中文字幕2019免费| 欧美日韩伦理一区二区| 成人免费看片视频在线观看| 国产精品一卡二卡在线观看| 久草成人在线视频| 亚洲国产精品高清久久久| 天堂在线中文网官网| 美女主播视频一区| 日本不卡一二三区黄网| 国产又黄又粗又猛又爽的| 日韩欧美资源站| 激情国产在线| 亚洲欧美国产精品桃花| 午夜精品久久久久久久久久蜜桃| 精品无人乱码一区二区三区的优势| 日韩午夜av在线| 国产手机在线观看| 4438x亚洲最大成人网| 欧美精品第三页| 国产精品资源站在线| 久久99久久98精品免观看软件| 亚洲国产精品电影在线观看| 欧美成人精品三级网站| 最新国产精品久久| 97se亚洲国产综合自在线不卡| 婷婷激情五月综合| 欧美大成色www永久网站婷| 欧美激情15p| 色啦啦av综合| 精品久久中文字幕| 欧美日韩在线看片| 国产视频99| 奇米精品一区二区三区四区| 中文字幕在线观看成人| 亚洲欧美日韩精品久久亚洲区 | 91麻豆桃色免费看| 日韩视频一区| 久久精品一区二区三区四区五区 | 欧美成人免费| 91中文字幕在线|