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

Go Metrics SDK Tag 校驗性能優化實踐

數據庫
本文主要以 Go Metrics SDK 為例,講述對打點 API 的 hot-path 優化的實踐。

背景

Metrics SDK 是與字節內場時序數據庫 ByteTSD 配套的用戶指標打點 SDK,在字節內數十萬服務中集成,應用廣泛,因此 SDK 的性能優化是個重要和持續性的話題。

用戶在使用 SDK API 進行打點時,需要傳入指標對應的 Tag:

tags := []m.T{{Name: "foo", Value: "a"}, {Name: "bar", Value: "b"}}
metric.WithTags(tags...).Emit(m.Incr(1))

SDK 內部需要對用戶傳入的 Tag Value 的合法性進行校驗,IsValidTagValue,是 SDK 中對 Tag Value 進行字符合法性校驗的 util 函數,在對內部一些用戶的業務使用 pprof 拉取 profile 時,發現這兩個函數的 CPU 消耗占整個打點 API 過程的10%~20%,由于該函數發生在打點 API 的 hot-path 上,因此有必要對其進行進一步優化。

圖片圖片

分析

當前實現

我們先看一下 IsValidTagValue 函數內部的實現方式,是否有可優化的點。當前的實現,對于通過 API 傳入的每一個Tag Value,會進行以下操作來判斷其合法性:

  • 先判斷是否是在 Letter、Number 的范圍內,是則直接通過;
  • 存儲所有允許的特殊字符白名單,遍歷 Tag Value 對比其每個字符是否在白名單內。
var (
   // these runes are valid in tag values
   whiteListRunes = []rune{'_', '-', '.', '%', ':', ' ', '[', ']', ',', '%',
      '/', ':', ';', '<', '=', '>', '@', '~'}
)
func IsValidTagValue(s string) bool {
   if len(s) == 0 || len(s) > maxTagLen {
      return false
   }
   for i, r := range s {
      if r < minValidChar || r > maxValidChar {
         return false
      }
      if unicode.IsLetter(r) || unicode.IsNumber(r) || isRuneInWhiteList(r) {
         continue
      }
      return false
   }
   return true
}

該實現的時間復雜度簡單分析如下:

O(n.)n : stringlength

對于全由特殊字符構成的字符串,其時間復雜度是:

O(m * n)n : stringlength, m : whitelistlength

整個字符串的時間復雜度將介于O(n)到O(m * n)之間

問題點

可以看到,從當前實現看,一個主要影響性能的點是白名單列表的循環遍歷對比操作,我們需要考慮可能的優化方式來降低這個操作的時間復雜度。

優化

優化一:使用 Lookup Table,空間換時間

Metrics SDK 所有允許的合法的字符,實際上是 ASCII 的一個子集,也就是說其所有可能的字符最多只有128個,因此,我們可以通過空間換時間的方式,將對白名單的 O(n) 遍歷操作轉換為 O(1) 的查表操作:

  1. 提前對這128個字符建立一個包含128個成員的數組,在每一個 offset 上標記對應字符是否合法(合法則標記為1),這樣就建立了一個快速的 lookup table
  2. 對于要校驗的每一個字符,只要將其轉化為數組 offset,直接取數組成員值判斷是否為1即可

image.pngimage.png

table := [128]uint8{...}
// fill flags
for i := 0; i < 128; i++ {
   if unicode.IsNumber(rune(i)) || unicode.IsLetter(rune(i)) || isRuneInWhiteList(rune(i)) {
      table[i] = 1
   }
}
str := "hello"
for _, char := range []byte(str) {
    if r > maxValidChar {
       return false
    }
    if table[char] != 1 {
        return false
    }
}
return true

Benchmark

goos: linux
goarch: amd64
pkg: code.byted.org/gopkg/metrics_core/utils
cpu: Intel(R) Xeon(R) Platinum 8260 CPU @ 2.40GHz
BenchmarkLookupAlgoValid
BenchmarkLookupAlgoValid/baseline
BenchmarkLookupAlgoValid/baseline-8                   2839345               478.9 ns/op
BenchmarkLookupAlgoValid/lookup-arraytable
BenchmarkLookupAlgoValid/lookup-arraytable-8          6673456               167.8 ns/op

可以看到,速度提升60%

優化二:使用 SIMD,提升并行度

基于 Lookup Table 的校驗方式,將字符串校驗的時間復雜度穩定在了O(n)n : stringlength, 但有沒有可能進一步減少對字符串每一個字符的遍歷次數,比如一次校驗16個字符?

我們知道,SIMD 指令是循環展開優化的常用思路,那么這里是否可以引入 SIMD 來進一步提升運算并行度和效率?

答案是肯定的,以 intel x86 架構為例,參考其 Intrinsics Guide,在不同的 SIMD 指令集上提供了多個可以實現在不同大小的 lookup table 中查找數據的指令,這些指令可以作為我們加速方案的基礎:

圖片圖片

注:可以通過 cat /proc/cpuinfo 命令來查看機器支持的simd指令集

鑒于 vpermi2b 指令的支持目前不是很普遍的原因,我們考慮使用 pshufb 來實現一個 SIMD 版本,但我們的Lookup Table 需要調整下,因為:

  • 雖然我們基于 bitmap 實現的 Lookup Table 是 128 bits,剛好可以填充 128 bits 的寄存器
  • 但 pshufb 是按字節進行 lookup 的,128 bits 的寄存器支持16字節的 lookup

因此,我們需要將 bitmap lookup table 做一次升維,變成一個16*8 bits 的二維 lookup table,做兩次遞進的行、列 lookup 完成查找,基于該思路,可以實現一次校驗16個字符,大大提升并行度。

整體方案

該方案主要參考這篇文章:SIMDized check which bytes are in a set(http://0x80.pl/articles/simd-byte-lookup.html)

構建 bitmap table

對于一個 ASCII 字符,我們用其低 4bits 作為 lookup table 的 row index,用高 3bits 作為 lookup table 的 column index,這樣對128個 ASCII 字符建立如下的一個二維 bitmap table:

圖片圖片

Lookup 流程

我們先實現一個純 go 語言版本的基于二維 bitmap lookup table 的方案,以便于理解其中的關鍵邏輯:

table := [16]uint8{}
// fill flags
for i := 0; i < 128; i++ {
   if unicode.IsNumber(rune(i)) || unicode.IsLetter(rune(i)) || isRuneInWhiteList(rune(i)) {
      lowerNibble := i & 0x0f
      upperNibble := i >> 4
      table[lowerNibble] |= 1 << upperNibble
   }
}
str := "hello"

for _, char := range []byte(str) {
    if r > maxValidChar {
       return false
    }
    lowerNibble := uint8(r) & 0x0f
    upperNibble := uint8(r) >> 4
    if table[lowerNibble]&(1<<upperNibble) == 0 {
       return false
    }
}
return true

如上代碼示例,可以看到,判斷某個字符合法的關鍵邏輯是:

  • 通過 table[lowerNibble] 獲取table第 lowerNibble 行內容,然后再看其第 upperNibble 個 bit 位是否為0

而 SIMD 版本,即是將上述的每一步操作都使用對應的 SIMD 指令變成對16個字節的并行操作,SIMD 的關鍵操作流程以及和上述 go 代碼的對應關系如下:

圖片圖片

代碼實現

在 go 語言中,想要使用 SIMD,需要寫 plan9 匯編,而編寫 plan9 通常有兩種方式:

  • 手撕,可借助 avo 這樣的工具
  • C code 轉 plan9,可借助 goat、c2goasm 這樣的工具

這里采用 C code 轉 plan9 的方式,先寫一個 C 版本:

注:由于 goat 工具限制,不能很好的支持 C 代碼中的常量定義,因此以下示例通過函數參數定義用到的 sm、hm 常量

#include <tmmintrin.h>
// is_valid_string returns 1 if all chars is in table, returns 0 else.
void is_valid_string(char* table, char* strptr, long strlen, char* sm, char* hm, char* rt) {
    __m128i bitmap = _mm_loadu_si128((__m128i*)table);
    __m128i shift_mask = _mm_loadu_si128((__m128i*)sm);
    __m128i high_mask = _mm_loadu_si128((__m128i*)hm);
    size_t n = strlen/16;
    for (size_t i = 0; i < n; i++)
    {
        __m128i input = _mm_loadu_si128((__m128i*)strptr);
        __m128i rows = _mm_shuffle_epi8(bitmap, input);
        __m128i hi_nibbles = _mm_and_si128(_mm_srli_epi16(input, 4), high_mask);
        __m128i cols = _mm_shuffle_epi8(shift_mask, hi_nibbles);
        __m128i tmp = _mm_and_si128(rows, cols);
        __m128i result = _mm_cmpeq_epi8(tmp, cols);
        size_t mask = _mm_movemask_epi8(result);
        if (mask != 65535) {
            *rt = 0;
            return;
        }
        strptr = strptr + 16;
    }
    size_t left = strlen%16;
    for (size_t i = 0; i < left; i++)
    {
        size_t lower = strptr[i] & 0x0f;
        size_t higher = strptr[i] >> 4;
        if ((table[lower] & (1<<higher)) == 0) {
            *rt = 0;
            return;
        }
    }
    *rt = 1;
    return;
}

通過以下命令轉為 plan9:

goat is_valid_string.c -03 -mssse3

生成的 plan9 代碼如下:

//go:build !noasm && amd64
// AUTO-GENERATED BY GOAT -- DO NOT EDIT
TEXT ·_is_valid_string(SB), $0-48
   MOVQ table+0(FP), DI
   MOVQ strptr+8(FP), SI
   MOVQ strlen+16(FP), DX
   MOVQ sm+24(FP), CX
   MOVQ hm+32(FP), R8
   MOVQ rt+40(FP), R9
   WORD $0x8949; BYTE $0xd2     // movq   %rdx, %r10
   LONG $0x3ffac149             // sarq   $63, %r10
   LONG $0x3ceac149             // shrq   $60, %r10
   WORD $0x0149; BYTE $0xd2     // addq   %rdx, %r10
   LONG $0x0f428d48             // leaq   15(%rdx), %rax
   LONG $0x1ff88348             // cmpq   $31, %rax
   JB   LBB0_4
   LONG $0x076f0ff3             // movdqu (%rdi), %xmm0
   LONG $0x096f0ff3             // movdqu (%rcx), %xmm1
   LONG $0x6f0f41f3; BYTE $0x10 // movdqu (%r8), %xmm2
   WORD $0x894d; BYTE $0xd0     // movq   %r10, %r8
   LONG $0x04f8c149             // sarq   $4, %r8
   WORD $0xc031                 // xorl   %eax, %eax
LBB0_2:
   LONG $0x1e6f0ff3               // movdqu   (%rsi), %xmm3
   LONG $0xe06f0f66               // movdqa   %xmm0, %xmm4
   LONG $0x00380f66; BYTE $0xe3   // pshufb   %xmm3, %xmm4
   LONG $0xd3710f66; BYTE $0x04   // psrlw    $4, %xmm3
   LONG $0xdadb0f66               // pand %xmm2, %xmm3
   LONG $0xe96f0f66               // movdqa   %xmm1, %xmm5
   LONG $0x00380f66; BYTE $0xeb   // pshufb   %xmm3, %xmm5
   LONG $0xe5db0f66               // pand %xmm5, %xmm4
   LONG $0xe5740f66               // pcmpeqb  %xmm5, %xmm4
   LONG $0xccd70f66               // pmovmskb %xmm4, %ecx
   LONG $0xfffff981; WORD $0x0000 // cmpl $65535, %ecx
   JNE  LBB0_8
   LONG $0x10c68348               // addq $16, %rsi
   LONG $0x01c08348               // addq $1, %rax
   WORD $0x394c; BYTE $0xc0       // cmpq %r8, %rax
   JB   LBB0_2
LBB0_4:
   LONG $0xf0e28349         // andq   $-16, %r10
   WORD $0xb041; BYTE $0x01 // movb   $1, %r8b
   WORD $0x294c; BYTE $0xd2 // subq   %r10, %rdx
   JE   LBB0_9
   WORD $0xc031             // xorl   %eax, %eax
LBB0_7:
   LONG $0x1cbe0f4c; BYTE $0x06 // movsbq (%rsi,%rax), %r11
   WORD $0x8945; BYTE $0xda     // movl   %r11d, %r10d
   LONG $0x0fe28341             // andl   $15, %r10d
   LONG $0x04ebc141             // shrl   $4, %r11d
   LONG $0x0cbe0f42; BYTE $0x17 // movsbl (%rdi,%r10), %ecx
   LONG $0xd9a30f44             // btl    %r11d, %ecx
   JAE  LBB0_8
   LONG $0x01c08348             // addq   $1, %rax
   WORD $0x3948; BYTE $0xd0     // cmpq   %rdx, %rax
   JB   LBB0_7
LBB0_9:
   WORD $0x8845; BYTE $0x01 // movb   %r8b, (%r9)
   BYTE $0xc3               // retq
LBB0_8:
   WORD $0x3145; BYTE $0xc0 // xorl   %r8d, %r8d
   WORD $0x8845; BYTE $0x01 // movb   %r8b, (%r9)
   BYTE $0xc3               // retq

對應的 Go Wrapper 代碼如下:

var (
        // these runes are valid in tag values
        whiteListRunes = []rune{'_', '-', '.', '%', ':', ' ', '[', ']', ',', '%',
                '/', ':', ';', '<', '=', '>', '@', '~'}
        rcBitTable [16]uint8
        smTable    [16]int8
        hmTable    [16]uint8
)
//go:noescape
func _is_valid_string(table unsafe.Pointer, str unsafe.Pointer, len int32, sm, hm unsafe.Pointer, rt unsafe.Pointer)
func init() {
        // build tables
        for i := 0; i < 128; i++ {
                if unicode.IsNumber(rune(i)) || unicode.IsLetter(rune(i)) || isRuneInWhiteList(rune(i)) {
                        lowerNibble := i & 0x0f
                        upperNibble := i >> 4
                        rcBitTable[lowerNibble] |= 1 << upperNibble
                }
        }
        smTable = [16]int8{1, 2, 4, 8, 16, 32, 64, -128, 1, 2, 4, 8, 16, 32, 64, -128}
        hmTable = [16]uint8{0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f}
}
func IsValidTagValueLookup2dBitTableSIMD(s string) bool {
        l := len(s)
        if l == 0 || len(s) > maxTagLen {
                return false
        }
        sptr := unsafe.Pointer((*reflect.StringHeader)(unsafe.Pointer(&s)).Data)
        var rt byte
        _is_valid_string(unsafe.Pointer(&rcBitTable), sptr, int32(len(s)), unsafe.Pointer(&smTable), unsafe.Pointer(&hmTable), unsafe.Pointer(&rt))
        return rt != 0
}

Benchmark

  1. 先做一個通用的 benchmark,待校驗的 string 長度從1 ~ 20不等:
goos: linux
goarch: amd64
pkg: code.byted.org/gopkg/metrics_core/utils
cpu: Intel(R) Xeon(R) Platinum 8260 CPU @ 2.40GHz
BenchmarkLookupAlgoValid
BenchmarkLookupAlgoValid/baseline
BenchmarkLookupAlgoValid/baseline-8                  2574217               510.5 ns/op
BenchmarkLookupAlgoValid/lookup-arraytable
BenchmarkLookupAlgoValid/lookup-arraytable-8         6347204               193.7 ns/op
BenchmarkLookupAlgoValid/lookup-2d-bittable-simd
BenchmarkLookupAlgoValid/lookup-2d-bittable-simd-8   6133671               185.2 ns/op

可以看到,SIMD 版本在平均水平上與 arraytable 相當

  1. 由于 SIMD 優勢主要體現在長字符串時,因此,我們使用一組長度為20左右的 string,再次 benchmark:
goos: linux
goarch: amd64
pkg: code.byted.org/gopkg/metrics_core/utils
cpu: Intel(R) Xeon(R) Platinum 8260 CPU @ 2.40GHz
BenchmarkLookupAlgoValidLong
BenchmarkLookupAlgoValidLong/baseline
BenchmarkLookupAlgoValidLong/baseline-8                  3523198           356.4 ns/op
BenchmarkLookupAlgoValidLong/lookup-arraytable
BenchmarkLookupAlgoValidLong/lookup-arraytable-8         8434142           153.3 ns/op
BenchmarkLookupAlgoValidLong/lookup-2d-bittable-simd
BenchmarkLookupAlgoValidLong/lookup-2d-bittable-simd-8  13621970            87.29 ns/op

可以看到,在長 string 上 SIMD 版本表現出非常大的優勢,相對于 arraytable 版本再次提升50%

結論

  • 通過 lookup table + SIMD 的方式優化,字符校驗的整體性能可以提升2~4倍
  • 但由于在 Go 中 plan9 匯編無法內聯,因此在待校驗的字符串較短時不能體現其優勢
責任編輯:龐桂玉 來源: 字節跳動技術團隊
相關推薦

2022-10-28 13:41:51

字節SDK監控

2024-01-03 16:29:01

Agent性能優化

2020-03-23 15:15:57

MySQL性能優化數據庫

2020-07-17 19:55:50

Vue前端性能優化

2010-07-06 09:07:09

2021-08-13 09:06:52

Go高性能優化

2021-09-24 14:02:53

性能優化實踐

2019-08-02 11:28:45

HadoopYARN調度系統

2022-03-29 13:27:22

Android優化APP

2025-05-15 07:11:51

2016-11-17 09:00:46

HBase優化策略

2012-12-24 09:55:15

JavaJava WebJava優化

2022-07-15 09:20:17

性能優化方案

2022-07-08 09:38:27

攜程酒店Flutter技術跨平臺整合

2017-03-01 20:53:56

HBase實踐

2014-03-19 14:34:06

JQuery高性能

2021-09-11 21:02:24

監控Sentry Web性能

2021-08-04 09:33:22

Go 性能優化

2023-12-30 18:35:37

Go識別應用程序

2025-05-21 08:15:00

GoAPI開發
點贊
收藏

51CTO技術棧公眾號

欧美一区二区视频网站| 国产精品色噜噜| 情事1991在线| 女同久久另类69精品国产| 秋霞影院一区| 欧美日韩精品中文字幕| 亚洲一区二区三区免费观看| 超碰免费在线97| 久久久久国产一区二区| 精品国产拍在线观看| 国产一级黄色录像| 四虎国产精品免费久久5151| 午夜精品123| 中文字幕欧美人与畜| 天天干视频在线观看| 麻豆久久一区二区| 欧美一级大片在线观看| 久久精品黄色片| 国产va免费精品观看精品视频| 91精品国产一区二区三区香蕉| 日本wwww视频| 女囚岛在线观看| 国产精品国产三级国产普通话三级 | 在线日韩一区二区| 成人免费看片'免费看| 中文日本在线观看| 久久先锋影音av鲁色资源网| 99国产超薄肉色丝袜交足的后果| 国产精品xxxxxx| 国产日韩专区| 久久久欧美一区二区| 精品亚洲乱码一区二区| 国产影视精品一区二区三区| 亚洲第一色中文字幕| 992kp免费看片| 福利一区和二区| 色天天综合色天天久久| 拔插拔插海外华人免费| av软件在线观看| 亚洲免费av在线| 伊人久久大香线蕉午夜av| 国产高清在线| 久久精品亚洲麻豆av一区二区 | 欧美日韩激情在线一区二区三区| 精品日韩欧美一区二区| 在线观看你懂的视频| 91丨精品丨国产| 欧美老肥妇做.爰bbww| 黄色片久久久久| 一区二区三区短视频| 欧美日韩免费一区| www黄色日本| 在线一区av| 色噜噜狠狠一区二区三区果冻| 成人免费在线小视频| 午夜av不卡| 日韩欧美在线一区| 美女网站免费观看视频| 欧美aaa大片视频一二区| 91成人在线精品| 日av中文字幕| 亚洲国产尤物| 9191久久久久久久久久久| 91日韩精品视频| www.欧美| 欧美成人福利视频| 香港三级日本三级| 国产综合久久久| 日韩中文理论片| 无码人妻精品一区二区三区夜夜嗨| 亚洲色图插插| 国产做受高潮69| 91丝袜一区二区三区| 日韩综合一区二区| 成人免费看片视频| 亚洲女同志亚洲女同女播放| 97se亚洲国产综合自在线| 欧美精品一区二区三区四区五区 | 久久夜色电影| 亚洲欧美成人一区二区在线电影| 亚洲ⅴ国产v天堂a无码二区| 亚洲天堂一区二区三区四区| 久久久女人电视剧免费播放下载| www.国产一区二区| 久久99在线观看| 国产亚洲福利社区| 亚洲精品在线电影| 日本一卡二卡在线播放| 欧美色123| 国产成人在线视频| 国产熟女一区二区丰满| 93久久精品日日躁夜夜躁欧美| 日韩午夜视频在线观看| 午夜激情在线| 色婷婷av一区二区三区gif | 中文字幕在线观看国产| 国产成人免费av在线| 欧美在线视频二区| 羞羞视频在线观看不卡| 一本大道久久a久久精品综合 | 99精品久久99久久久久| 亚洲v欧美v另类v综合v日韩v| 日韩欧美一起| 欧美三级蜜桃2在线观看| 久久久久久久久久久影视| 国产精品一区二区99| 欧美高清在线观看| 中文字幕欧美人妻精品| 99国产精品久久久久久久久久| 一区二区国产日产| 自拍偷拍亚洲视频| 日韩精品中文字幕在线不卡尤物| 老熟妇一区二区| 国产精品mm| 国产自摸综合网| 国产九九在线| 欧美日韩国产限制| 日批视频免费看| 国产精品久久观看| 国产成人免费av| 无码国精品一区二区免费蜜桃| 亚洲视频精选在线| 污色网站在线观看| 午夜a一级毛片亚洲欧洲| 欧美国产乱视频| 国产熟女一区二区丰满| 国产精品电影一区二区三区| 人妻有码中文字幕| 久久99偷拍| 欧美激情国产日韩精品一区18| 一级片一区二区三区| 久久精品日韩一区二区三区| 免费看国产曰批40分钟| 亚洲精品一区在线| 不卡av在线网站| 中文字幕在线播放不卡| 国产精品蜜臀av| 黑森林福利视频导航| 青青一区二区| 97久久精品国产| 欧美性受xxxx狂喷水| 一区二区三区中文免费| 国产精品熟女一区二区不卡| 2023国产精品久久久精品双| 国产一区二区色| 日本中文字幕电影在线免费观看| 欧美三级电影在线看| 伊人影院综合网| 免费高清成人在线| 亚洲精品一卡二卡三卡四卡| 777午夜精品电影免费看| 在线亚洲自拍| 中文字幕欧美日韩| 无码任你躁久久久久久久| 91免费国产视频网站| 黄色片视频在线免费观看| 久9久9色综合| 国产剧情久久久久久| 伦xxxx在线| 日韩一区二区精品葵司在线| 久久久.www| 99免费精品在线观看| wwwxxx黄色片| 欧美国产一级| 91亚色免费| 1区2区3区在线| 亚洲精品网址在线观看| 中文字幕一区二区三区四区欧美| 国产女主播视频一区二区| 国产精品v日韩精品v在线观看| 国产精品久久久久久久久妇女| 亚洲最大的网站| mm视频在线视频| 亚洲天堂男人天堂| 国产美女自慰在线观看| 亚洲福利视频一区| 97超碰在线资源| 久草中文综合在线| 蜜臀精品一区二区| 亚洲美女久久| 91九色视频在线| 91jq激情在线观看| 一本色道久久综合狠狠躁篇怎么玩| 在线观看免费高清视频| 亚洲精品v日韩精品| 中文字幕日韩三级片| 免费成人美女在线观看| 99久久99久久精品| 亚洲综合小说图片| 91免费在线视频网站| 久久青草伊人| 久久天堂av综合合色| 午夜影院在线视频| 欧美一区二区视频在线观看| 西西44rtwww国产精品| 国产精品久久久久一区二区三区共| 国产亚洲精品成人a| 日韩电影网1区2区| 日韩精品在线观看av| 波多野结衣在线观看一区二区| 波多野结衣久草一区| 日韩欧美少妇| 91精品国产成人| av网站大全在线| 国产亚洲精品91在线| 亚洲乱熟女一区二区| 欧美日韩一区二区三区在线| 欧美三级韩国三级日本三斤在线观看| 中文字幕精品一区二区三区精品| 日韩无码精品一区二区| 狠狠网亚洲精品| 日本熟妇人妻中出| 99热精品在线| www.男人天堂网| 色综合色综合| 欧美下载看逼逼| 久久成人福利| 99久久一区三区四区免费| 国产乱子精品一区二区在线观看| 久久久久久久网站| 97超碰资源站在线观看| 中文字幕在线观看日韩| 欧美美女搞黄| 亚洲精品美女免费| 韩国av免费在线观看| 91精品国产综合久久精品| 在线免费一级片| 日本道精品一区二区三区| 国产精品第9页| 一区二区三区四区亚洲| 国产激情无码一区二区三区| 中文字幕乱码亚洲精品一区| 国产美女免费网站| 国产亚洲欧美中文| 免费a级黄色片| 96av麻豆蜜桃一区二区| 黑丝av在线播放| 不卡视频在线看| 天天躁日日躁狠狠躁av麻豆男男| 国产999精品久久久久久| 麻豆精品国产传媒| 国产精品白丝jk黑袜喷水| 亚洲女人在线观看| 国产剧情一区在线| avtt中文字幕| 成人午夜视频福利| 亚洲视频在线播放免费| 99r国产精品| 国产精品三级在线观看无码| 91小视频免费看| www.久久国产| 国产欧美一区二区在线观看| 亚洲ⅴ国产v天堂a无码二区| 国产精品家庭影院| 国产盗摄一区二区三区在线| 亚洲一区在线免费观看| 国产成人精品亚洲男人的天堂| 亚洲午夜精品在线| 亚洲日本韩国在线| 色婷婷av久久久久久久| 一区二区日韩在线观看| 91精品久久久久久久91蜜桃| 午夜精品一二三区| 亚洲成人激情视频| 内衣办公室在线| 中文字幕亚洲无线码在线一区| 日本免费视频在线观看| 欧美日韩成人免费| 小早川怜子影音先锋在线观看| 国产成人精品视| 日本国产一区| www.久久爱.cn| 亚洲区小说区图片区qvod按摩| 日韩欧美一区二区在线观看| 小说区亚洲自拍另类图片专区| 日韩精品福利片午夜免费观看| 亚洲大片在线| 老司机午夜av| 国产精品自拍在线| 9.1成人看片| 国产精品毛片无遮挡高清| 欧美日韩精品亚洲精品| 欧美性猛交xxxx富婆| 一级特黄录像免费看| 欧美精品一区二区三区蜜臀| 日本人妖在线| 久热国产精品视频| 亚洲人成在线网站| 成人xvideos免费视频| 久久99精品久久久久久欧洲站| 性欧美.com| 亚洲精品韩国| 天天操狠狠操夜夜操| 成人精品高清在线| 在线看片中文字幕| 亚洲成在线观看| 伊人久久亚洲综合| 精品国产免费一区二区三区四区| 国产一区电影| 久久久久久成人| 日韩精品第二页| 欧美理论一区二区| 欧美视频在线观看| 尤蜜粉嫩av国产一区二区三区| 懂色av中文一区二区三区| 人与嘼交av免费| 欧美色播在线播放| 亚洲精品.www| 久久精品久久久久电影| 天天免费亚洲黑人免费| 国产欧美韩日| 午夜欧美视频| 国产aaaaa毛片| www激情久久| 国产亚洲成人精品| 欧美精品日韩一区| 国产大学生校花援交在线播放| 97国产suv精品一区二区62| 国产精品日本一区二区三区在线| 欧洲精品久久| 国产精品久久久一区二区| av在线天堂网| 亚洲精品视频在线看| 亚洲一区二区影视| 永久免费毛片在线播放不卡 | 清纯唯美亚洲综合| 粉嫩av一区二区| 国产精品一二三在线观看| 麻豆一区二区99久久久久| 日本二区在线观看| 日韩欧美中文字幕在线播放| 无码精品视频一区二区三区| 久久久久九九九九| 一区二区网站| 国产精品免费看久久久无码| 国内精品伊人久久久久av一坑| 一级二级黄色片| 欧美性生交片4| 第三区美女视频在线| 日韩美女在线观看| 国产欧美日韩在线一区二区| 国产a视频免费观看| 久久久蜜桃精品| 久久亚洲精品石原莉奈| 亚洲社区在线观看| 777午夜精品电影免费看| 亚洲二区三区四区| 麻豆成人久久精品二区三区小说| 99国产精品免费| 欧美日韩精品一区二区三区| 日韩伦理在线观看| 91香蕉亚洲精品| 欧美精品日本| www国产视频| 懂色av中文一区二区三区天美| 婷婷色在线观看| 欧美在线观看一区二区三区| 亚洲瘦老头同性70tv| 日本一极黄色片| 国产精品美女久久久久久久久久久| 欧美另类高清videos的特点| 日韩一中文字幕| 婷婷综合国产| 亚洲熟妇av日韩熟妇在线| 久久久久久久久岛国免费| 国产日韩久久久| 久久久国产一区二区| 999久久久久久久久6666| 免费观看美女裸体网站| 久久中文娱乐网| 一区二区小视频| 欧美夫妻性生活视频| 亚洲精华一区二区三区| 中文久久久久久| 一区二区三区高清不卡| 天天干天天爽天天操| 国产精品福利在线观看| 欧美一区二区三区久久精品| 国产精品麻豆入口| 欧美曰成人黄网| 久久不射影院| 青娱乐国产91| 国产一区二区久久| 在线观看日本视频| 麻豆国产精品va在线观看不卡| 老牛国内精品亚洲成av人片| www日韩视频| 亚洲午夜久久久久久久久久久| 噜噜噜在线观看播放视频| 91美女片黄在线观看游戏| 亚洲欧美日韩精品一区二区| 欧美巨胸大乳hitomi| 欧美成人精品二区三区99精品| 欧美xxxxxx| 成人免费在线视频播放| 国产欧美一区二区三区在线看蜜臀| 国产不卡av在线播放| 国产99视频精品免视看7| 中国成人一区| 国产免费无遮挡吸奶头视频|