zoukankan      html  css  js  c++  java
  • 测试VGA12H直接写屏速度

    File:      VGASpeed.txt
    Name:      测试VGA12H模式的速度
    Author:    zyl910
    Blog:      http://blog.csdn.net/zyl910/
    Version:   V1.0
    Updata:    2006-11-14

    下载(注意修改下载后的扩展名)


    简介
    ~~~~
      DOS下直接写屏的代码写过不少了,但一直没有想过一个问题——操作VGA的速度有多块。因此,我写了个小程序来测试VGA的速度。
      图形模式:VGA 12h,640*480*16色。
      三个测试项目:
        1.读测试。使用VGA读模式0,逐扫描行逐位平面的将显存数据复制到系统内存。
        2.写测试。使用VGA写模式0,逐扫描行逐位平面的将系统内存数据复制到显存。
        3.在等待垂直回扫情况下的写测试。
      四种访问方式:用C语言远指针、movsb、movsw、movsd

    测试结果
    ~~~~~~~~

    CPU   : AMD Athlon XP 1700+(实际频率:1463 MHz (11 x 133))
    内存  : DDR266 256MB
    显卡  : NVIDIA GeForce2 MX/MX 400(AGP 4X)
    显存带宽: 125MHz * 128bit = 2000MB/s
    操作系统: Windows XP SP2
    [FPS]
    R_C    :         11.7646
    W_C    :         51.5834
    R_BYTE :         12.0000
    W_BYTE :         86.4751
    R_WORD :         23.6298
    W_WORD :        124.8862
    R_DWORD:         44.7459
    W_DWORD:        156.8619
    WaitW_B:         60.0298
    WaitW_W:         59.9293
    WaitW_D:         59.9293
    124.8862 /  86.4751 = 144.42%
    156.8619 / 124.8862 = 125.60%

    CPU   : AMD Athlon XP 1700+(实际频率:1463 MHz (11 x 133))
    内存  : DDR266 256MB
    显卡  : NVIDIA GeForce2 MX/MX 400(AGP 4X)
    显存带宽: 125MHz * 128bit = 2000MB/s
    操作系统: Windows 98SE
    [FPS]
    R_C    :         11.6641
    W_C    :         60.7337
    R_BYTE :         11.9657
    W_BYTE :         98.8431
    R_WORD :         23.4287
    W_WORD :        173.9558
    R_DWORD:         44.4442
    W_DWORD:        267.9724
    WaitW_B:         59.9293
    WaitW_W:         59.9293
    WaitW_D:         60.0298
    173.9558 /  98.8431 = 175.99%
    267.9724 / 173.9558 = 154.05%


    CPU   : AMD Athlon XP 1700+(实际频率:1463 MHz (11 x 133))
    内存  : DDR266 256MB
    显卡  : NVIDIA GeForce2 MX/MX 400(AGP 4X)
    显存带宽: 125MHz * 128bit = 2000MB/s
    操作系统: DOS实模式
    [FPS]
    R_C    :         11.7646
    W_C    :         61.2365
    R_BYTE :         12.0663
    W_BYTE :        107.9934
    R_WORD :         23.6298
    W_WORD :        190.6475
    R_DWORD:         44.9470
    W_DWORD:        279.1337
    WaitW_B:         60.0298
    WaitW_W:         59.9293
    WaitW_D:         60.0298
    190.6475 / 107.9934 = 176.54%
    279.1337 / 190.6475 = 146.41%

    CPU   : Intel Celeron 2.53GHz
    内存  : Dual DDR333 512MB
    显卡  : NVIDIA RIVA TNT2 Model 64(AGP 4X)
    显存带宽: 110MHz * 64bit = 880MB/s
    操作系统: Windows XP SP2
    [FPS]
    R_C    :          8.4464
    W_C    :         37.5061
    R_BYTE :          8.4000
    W_BYTE :         46.1536
    R_WORD :         16.2895
    W_WORD :         64.1525
    R_DWORD:         31.1713
    W_DWORD:         78.9337
    WaitW_B:         29.8641
    WaitW_W:         59.3260
    WaitW_D:         59.5271
    64.1525 / 46.1536 = 138.99%
    78.9337 / 64.1525 = 123.04%

    CPU   : Intel Celeron, 1800 MHz (18 x 100)
    内存  : DDR266 256MB
    显卡  : nVIDIA GeForce4 MX 440(AGP 8X)
    显存带宽: 405MHz * 64bit = 3240MB/s
    操作系统: Windows XP SP2
    [FPS]
    R_C    :          7.7425
    W_C    :         33.1823
    R_BYTE :          7.8000
    W_BYTE :         42.9359
    R_WORD :         15.0829
    W_WORD :         56.5105
    R_DWORD:         28.8586
    W_DWORD:         68.5768
    WaitW_B:         28.6575
    WaitW_W:         49.2707
    WaitW_D:         55.2033
    56.5105 / 42.9359 = 131.62%
    68.5768 / 56.5105 = 121.35%

    分析
    ~~~~

    一、刷新率是60帧
      “在等待垂直回扫情况下的写测试”的测试结果都差不多,这表示VGA12H模式下的刷新率为60帧。


    二、读的速度比写的慢的多
      可能是因为在设计VGA硬件时,考虑到显存一般是用来输出的,所以专门为写操作优化的。
      由于读速度过慢,所以VGA的一些需要读显存的硬件加速特性——循环移位、位图合并模式——并不能提高性能,反而有可能拖后腿。


    三、movsw/movsd对性能的提升没有想象中得那么高
      对于读测试,movsw/movsd能使性能翻倍。
      可对于写测试,movsw/movsd虽然能提高性能,但并没翻倍。
      但是我们为了追求速度,还是坚持使用movsd方式吧。
      注意写模式1只支持movsb。


    四、为什么速度这么慢
      VGA12H模式的分辨率是640*480*16色,所以每帧图像大小为:640*480*4/8 = 153600(Byte)
      AGP总线的频率为66Mhz,如果每个时钟复制一个字节,那么理论上的帧率为:66Mhz * 1BytePerHz / 153600 = 429.6875fps
      而实际的movsb的测试结果是100帧左右,只有理论值的1/4。若再考虑AGP 4X使频率提高4倍,那么差距更大。
      可能是因为:当显卡将帧数据发送到显示器时,不可访问主表面的显存。但是VGA12H下只有一个主表面(VGA显存是256KB),放不下离屏表面,无法利用双缓冲加速。


    测试代码
    ~~~~~~~~

     

    /*
    File:      VGASpeed.c
    Name:      测试VGA12H模式的速度
    Author:    zyl910
    Blog:      http://blog.csdn.net/zyl910/
    Version:   V1.0
    Updata:    2006-11-14
    */
    #include <stdio.h>
    #include <conio.h>
    #include <mem.h>
    #include <dos.h>

    typedef unsigned char BYTE;
    typedef unsigned int  WORD;
    typedef unsigned long DWORD;
    typedef void far* LPVOID;

    #define SCR_W 640
    #define SCR_H 480
    #define SCR_PLANES 4
    #define SCANSIZE_DIB ((SCR_W)/2)
    #define SCANSIZE_VGA ((SCR_W)/8)
    #define SEG_VIDEO 0xA000
    #define WaitVR() while(!(inportb(0x3da)&0x08))
    static volatile DWORD far* const pbiosclock = MK_FP(0x0040, 0x6C);
    #define BIOSCLOCK_F ((double)18.2)
    void repmovsb(LPVOID lpD, LPVOID lpS, WORD cBytes)
    {
     _asm{
      push ds
      push es
      mov cx, cBytes
      les di, lpD
      lds si, lpS
      rep movsb
      pop es
      pop ds;
     }
    }
    void repmovsw(LPVOID lpD, LPVOID lpS, WORD cWords)
    {
     _asm{
      push ds
      push es
      mov cx, cWords
      les di, lpD
      lds si, lpS
      rep movsw
      pop es
      pop ds;
     }
    }
    void repmovsd(LPVOID lpD, LPVOID lpS, WORD cDWords)
    {
     _asm{
      push ds
      push es
      mov cx, cDWords
      les di, lpD
      lds si, lpS
      db 0x66; rep movsw; /* rep movsd */
      pop es
      pop ds
     }
    }
    int main(void)
    {
     BYTE byVGA[SCR_PLANES][SCANSIZE_VGA];
     DWORD cntF;
     int iX, iY;
     BYTE iP;
     WORD pscan;
     BYTE far *pbyV;
     BYTE *pbyM;
     BYTE bymask;
     DWORD tmrold, tmrcur, tmrover;
     double fpsR_C, fpsR_BYTE, fpsR_WORD, fpsR_DWORD;
     double fpsW_C, fpsW_BYTE, fpsW_WORD, fpsW_DWORD;
     double fpsWaitW_BYTE, fpsWaitW_WORD, fpsWaitW_DWORD;
     /* init VGA 12h: 640*480*4bit */
     _asm{
      mov ax, 0x0012;
      int 0x10;
      cld;
     }
     printf("Testing...");
     /* R:C */
     do{
      cntF = 0;
      tmrold = *pbiosclock;
      tmrover = tmrold + (DWORD)(BIOSCLOCK_F * 10); /* 10s */
      do{
       pscan = 0;
       for(iY=0; iY<SCR_H; iY++)
       {
        for(iP=0; iP<SCR_PLANES; iP++)
        {
         _asm{
          mov dx, 0x3CE; /* gc[4]:Read Map Select */
          mov al, 4;
          out dx, al;
          inc dx;
          mov al, iP;
          out dx, al;
         }
         pbyM = byVGA[iP];
         pbyV = MK_FP(SEG_VIDEO, pscan);
         for(iX=0; iX<SCANSIZE_VGA; iX++)
         {
          *pbyM++ = *pbyV++;
         }
        }
        pscan += SCANSIZE_VGA;
       }
       cntF++;
       tmrcur = *pbiosclock;
      }while((tmrcur<tmrover)&&(tmrcur>=tmrold));
      if (tmrcur < tmrold) continue;
     }while(0);
     fpsR_C = cntF / ((tmrcur-tmrold)/BIOSCLOCK_F);
     /* W:C */
     do{
      cntF = 0;
      tmrold = *pbiosclock;
      tmrover = tmrold + (DWORD)(BIOSCLOCK_F * 10); /* 10s */
      do{
       memset(byVGA[0], -(1&(((int)cntF)>>0)), SCANSIZE_VGA);
       memset(byVGA[1], -(1&(((int)cntF)>>1)), SCANSIZE_VGA);
       memset(byVGA[2], -(1&(((int)cntF)>>2)), SCANSIZE_VGA);
       memset(byVGA[3], -(1&(((int)cntF)>>3)), SCANSIZE_VGA);
       pscan = 0;
       for(iY=0; iY<SCR_H; iY++)
       {
        bymask = 1;
        for(iP=0; iP<SCR_PLANES; iP++)
        {
         _asm{
          mov dx, 0x3C4; /* sc[2]:Map Mask */
          mov al, 2;
          out dx, al;
          inc dx;
          mov al, bymask;
          out dx, al;
         }
         pbyM = byVGA[iP];
         pbyV = MK_FP(SEG_VIDEO, pscan);
         for(iX=0; iX<SCANSIZE_VGA; iX++)
         {
          *pbyV++ = *pbyM++;
         }
         bymask <<= 1;
        }
        pscan += SCANSIZE_VGA;
       }
       cntF++;
       tmrcur = *pbiosclock;
      }while((tmrcur<tmrover)&&(tmrcur>=tmrold));
      if (tmrcur < tmrold) continue;
     }while(0);
     fpsW_C = cntF / ((tmrcur-tmrold)/BIOSCLOCK_F);
     /* R:Byte */
     do{
      cntF = 0;
      tmrold = *pbiosclock;
      tmrover = tmrold + (DWORD)(BIOSCLOCK_F * 10); /* 10s */
      do{
       pscan = 0;
       for(iY=0; iY<SCR_H; iY++)
       {
        for(iP=0; iP<SCR_PLANES; iP++)
        {
         _asm{
          mov dx, 0x3CE; /* gc[4]:Read Map Select */
          mov al, 4;
          out dx, al;
          inc dx;
          mov al, iP;
          out dx, al;
         }
         repmovsb(byVGA[iP], MK_FP(SEG_VIDEO, pscan), SCANSIZE_VGA);
        }
        pscan += SCANSIZE_VGA;
       }
       cntF++;
       tmrcur = *pbiosclock;
      }while((tmrcur<tmrover)&&(tmrcur>=tmrold));
      if (tmrcur < tmrold) continue;
     }while(0);
     fpsR_BYTE = cntF / ((tmrcur-tmrold)/BIOSCLOCK_F);
     /* W:BYTE */
     do{
      cntF = 0;
      tmrold = *pbiosclock;
      tmrover = tmrold + (DWORD)(BIOSCLOCK_F * 10); /* 10s */
      do{
       memset(byVGA[0], -(1&(((int)cntF)>>0)), SCANSIZE_VGA);
       memset(byVGA[1], -(1&(((int)cntF)>>1)), SCANSIZE_VGA);
       memset(byVGA[2], -(1&(((int)cntF)>>2)), SCANSIZE_VGA);
       memset(byVGA[3], -(1&(((int)cntF)>>3)), SCANSIZE_VGA);
       pscan = 0;
       for(iY=0; iY<SCR_H; iY++)
       {
        bymask = 1;
        for(iP=0; iP<SCR_PLANES; iP++)
        {
         _asm{
          mov dx, 0x3C4; /* sc[2]:Map Mask */
          mov al, 2;
          out dx, al;
          inc dx;
          mov al, bymask;
          out dx, al;
         }
         repmovsb(MK_FP(SEG_VIDEO, pscan), byVGA[iP], SCANSIZE_VGA);
         bymask <<= 1;
        }
        pscan += SCANSIZE_VGA;
       }
       cntF++;
       tmrcur = *pbiosclock;
      }while((tmrcur<tmrover)&&(tmrcur>=tmrold));
      if (tmrcur < tmrold) continue;
     }while(0);
     fpsW_BYTE = cntF / ((tmrcur-tmrold)/BIOSCLOCK_F);
     /* R:Word */
     do{
      cntF = 0;
      tmrold = *pbiosclock;
      tmrover = tmrold + (DWORD)(BIOSCLOCK_F * 10); /* 10s */
      do{
       pscan = 0;
       for(iY=0; iY<SCR_H; iY++)
       {
        for(iP=0; iP<SCR_PLANES; iP++)
        {
         _asm{
          mov dx, 0x3CE; /* gc[4]:Read Map Select */
          mov al, 4;
          out dx, al;
          inc dx;
          mov al, iP;
          out dx, al;
         }
         repmovsw(byVGA[iP], MK_FP(SEG_VIDEO, pscan), SCANSIZE_VGA/2);
        }
        pscan += SCANSIZE_VGA;
       }
       cntF++;
       tmrcur = *pbiosclock;
      }while((tmrcur<tmrover)&&(tmrcur>=tmrold));
      if (tmrcur < tmrold) continue;
     }while(0);
     fpsR_WORD = cntF / ((tmrcur-tmrold)/BIOSCLOCK_F);
     /* W:WORD */
     do{
      cntF = 0;
      tmrold = *pbiosclock;
      tmrover = tmrold + (DWORD)(BIOSCLOCK_F * 10); /* 10s */
      do{
       memset(byVGA[0], -(1&(((int)cntF)>>0)), SCANSIZE_VGA);
       memset(byVGA[1], -(1&(((int)cntF)>>1)), SCANSIZE_VGA);
       memset(byVGA[2], -(1&(((int)cntF)>>2)), SCANSIZE_VGA);
       memset(byVGA[3], -(1&(((int)cntF)>>3)), SCANSIZE_VGA);
       pscan = 0;
       for(iY=0; iY<SCR_H; iY++)
       {
        bymask = 1;
        for(iP=0; iP<SCR_PLANES; iP++)
        {
         _asm{
          mov dx, 0x3C4; /* sc[2]:Map Mask */
          mov al, 2;
          out dx, al;
          inc dx;
          mov al, bymask;
          out dx, al;
         }
         repmovsw(MK_FP(SEG_VIDEO, pscan), byVGA[iP], SCANSIZE_VGA/2);
         bymask <<= 1;
        }
        pscan += SCANSIZE_VGA;
       }
       cntF++;
       tmrcur = *pbiosclock;
      }while((tmrcur<tmrover)&&(tmrcur>=tmrold));
      if (tmrcur < tmrold) continue;
     }while(0);
     fpsW_WORD = cntF / ((tmrcur-tmrold)/BIOSCLOCK_F);
     /* R:DWord */
     do{
      cntF = 0;
      tmrold = *pbiosclock;
      tmrover = tmrold + (DWORD)(BIOSCLOCK_F * 10); /* 10s */
      do{
       pscan = 0;
       for(iY=0; iY<SCR_H; iY++)
       {
        for(iP=0; iP<SCR_PLANES; iP++)
        {
         _asm{
          mov dx, 0x3CE; /* gc[4]:Read Map Select */
          mov al, 4;
          out dx, al;
          inc dx;
          mov al, iP;
          out dx, al;
         }
         repmovsd(byVGA[iP], MK_FP(SEG_VIDEO, pscan), SCANSIZE_VGA/4);
        }
        pscan += SCANSIZE_VGA;
       }
       cntF++;
       tmrcur = *pbiosclock;
      }while((tmrcur<tmrover)&&(tmrcur>=tmrold));
      if (tmrcur < tmrold) continue;
     }while(0);
     fpsR_DWORD = cntF / ((tmrcur-tmrold)/BIOSCLOCK_F);
     /* W:DWORD */
     do{
      cntF = 0;
      tmrold = *pbiosclock;
      tmrover = tmrold + (DWORD)(BIOSCLOCK_F * 10); /* 10s */
      do{
       memset(byVGA[0], -(1&(((int)cntF)>>0)), SCANSIZE_VGA);
       memset(byVGA[1], -(1&(((int)cntF)>>1)), SCANSIZE_VGA);
       memset(byVGA[2], -(1&(((int)cntF)>>2)), SCANSIZE_VGA);
       memset(byVGA[3], -(1&(((int)cntF)>>3)), SCANSIZE_VGA);
       pscan = 0;
       for(iY=0; iY<SCR_H; iY++)
       {
        bymask = 1;
        for(iP=0; iP<SCR_PLANES; iP++)
        {
         _asm{
          mov dx, 0x3C4; /* sc[2]:Map Mask */
          mov al, 2;
          out dx, al;
          inc dx;
          mov al, bymask;
          out dx, al;
         }
         repmovsd(MK_FP(SEG_VIDEO, pscan), byVGA[iP], SCANSIZE_VGA/4);
         bymask <<= 1;
        }
        pscan += SCANSIZE_VGA;
       }
       cntF++;
       tmrcur = *pbiosclock;
      }while((tmrcur<tmrover)&&(tmrcur>=tmrold));
      if (tmrcur < tmrold) continue;
     }while(0);
     fpsW_DWORD = cntF / ((tmrcur-tmrold)/BIOSCLOCK_F);
     /* WaitW:BYTE */
     do{
      cntF = 0;
      tmrold = *pbiosclock;
      tmrover = tmrold + (DWORD)(BIOSCLOCK_F * 10); /* 10s */
      do{
       memset(byVGA[0], -(1&(((int)cntF)>>0)), SCANSIZE_VGA);
       memset(byVGA[1], -(1&(((int)cntF)>>1)), SCANSIZE_VGA);
       memset(byVGA[2], -(1&(((int)cntF)>>2)), SCANSIZE_VGA);
       memset(byVGA[3], -(1&(((int)cntF)>>3)), SCANSIZE_VGA);
       pscan = 0;
       WaitVR();
       for(iY=0; iY<SCR_H; iY++)
       {
        bymask = 1;
        for(iP=0; iP<SCR_PLANES; iP++)
        {
         _asm{
          mov dx, 0x3C4; /* sc[2]:Map Mask */
          mov al, 2;
          out dx, al;
          inc dx;
          mov al, bymask;
          out dx, al;
         }
         repmovsb(MK_FP(SEG_VIDEO, pscan), byVGA[iP], SCANSIZE_VGA);
         bymask <<= 1;
        }
        pscan += SCANSIZE_VGA;
       }
       cntF++;
       tmrcur = *pbiosclock;
      }while((tmrcur<tmrover)&&(tmrcur>=tmrold));
      if (tmrcur < tmrold) continue;
     }while(0);
     fpsWaitW_BYTE = cntF / ((tmrcur-tmrold)/BIOSCLOCK_F);
     /* WaitW:WORD */
     do{
      cntF = 0;
      tmrold = *pbiosclock;
      tmrover = tmrold + (DWORD)(BIOSCLOCK_F * 10); /* 10s */
      do{
       memset(byVGA[0], -(1&(((int)cntF)>>0)), SCANSIZE_VGA);
       memset(byVGA[1], -(1&(((int)cntF)>>1)), SCANSIZE_VGA);
       memset(byVGA[2], -(1&(((int)cntF)>>2)), SCANSIZE_VGA);
       memset(byVGA[3], -(1&(((int)cntF)>>3)), SCANSIZE_VGA);
       pscan = 0;
       WaitVR();
       for(iY=0; iY<SCR_H; iY++)
       {
        bymask = 1;
        for(iP=0; iP<SCR_PLANES; iP++)
        {
         _asm{
          mov dx, 0x3C4; /* sc[2]:Map Mask */
          mov al, 2;
          out dx, al;
          inc dx;
          mov al, bymask;
          out dx, al;
         }
         repmovsw(MK_FP(SEG_VIDEO, pscan), byVGA[iP], SCANSIZE_VGA/2);
         bymask <<= 1;
        }
        pscan += SCANSIZE_VGA;
       }
       cntF++;
       tmrcur = *pbiosclock;
      }while((tmrcur<tmrover)&&(tmrcur>=tmrold));
      if (tmrcur < tmrold) continue;
     }while(0);
     fpsWaitW_WORD = cntF / ((tmrcur-tmrold)/BIOSCLOCK_F);
     /* WaitW:DWORD */
     do{
      cntF = 0;
      tmrold = *pbiosclock;
      tmrover = tmrold + (DWORD)(BIOSCLOCK_F * 10); /* 10s */
      do{
       memset(byVGA[0], -(1&(((int)cntF)>>0)), SCANSIZE_VGA);
       memset(byVGA[1], -(1&(((int)cntF)>>1)), SCANSIZE_VGA);
       memset(byVGA[2], -(1&(((int)cntF)>>2)), SCANSIZE_VGA);
       memset(byVGA[3], -(1&(((int)cntF)>>3)), SCANSIZE_VGA);
       pscan = 0;
       WaitVR();
       for(iY=0; iY<SCR_H; iY++)
       {
        bymask = 1;
        for(iP=0; iP<SCR_PLANES; iP++)
        {
         _asm{
          mov dx, 0x3C4; /* sc[2]:Map Mask */
          mov al, 2;
          out dx, al;
          inc dx;
          mov al, bymask;
          out dx, al;
         }
         repmovsd(MK_FP(SEG_VIDEO, pscan), byVGA[iP], SCANSIZE_VGA/4);
         bymask <<= 1;
        }
        pscan += SCANSIZE_VGA;
       }
       cntF++;
       tmrcur = *pbiosclock;
      }while((tmrcur<tmrover)&&(tmrcur>=tmrold));
      if (tmrcur < tmrold) continue;
     }while(0);
     fpsWaitW_DWORD = cntF / ((tmrcur-tmrold)/BIOSCLOCK_F);
     /* Exit VGA */
     _asm{
      mov ax, 0x0003;
      int 0x10;
     }
     /* out */
     printf("[FPS]/n");
     printf("R_C    :%16.4f/n", fpsR_C);
     printf("W_C    :%16.4f/n", fpsW_C);
     printf("R_BYTE :%16.4f/n", fpsR_BYTE);
     printf("W_BYTE :%16.4f/n", fpsW_BYTE);
     printf("R_WORD :%16.4f/n", fpsR_WORD);
     printf("W_WORD :%16.4f/n", fpsW_WORD);
     printf("R_DWORD:%16.4f/n", fpsR_DWORD);
     printf("W_DWORD:%16.4f/n", fpsW_DWORD);
     printf("WaitW_B:%16.4f/n", fpsWaitW_BYTE);
     printf("WaitW_W:%16.4f/n", fpsWaitW_WORD);
     printf("WaitW_D:%16.4f/n", fpsWaitW_DWORD);
     return 0;
    }

  • 相关阅读:
    CTR校准
    CTR的贝叶斯平滑
    FTRL 使用tensorflow的实现
    深入理解AUC
    tensorflow wide deep 介绍
    什么是卷积神经网络?为什么它们很重要?
    深度学习中 Batch Normalization为什么效果好
    处理excel将下标转换为ABCD列
    ssh无法登录,提示Pseudo-terminal will not be allocated because stdin is not a terminal.
    sudo: no tty present and no askpass program specified
  • 原文地址:https://www.cnblogs.com/zyl910/p/2186632.html
Copyright © 2011-2022 走看看