小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

探討SSE指令 - cutepig's blog - 博客園

 ShaneWu 2009-11-03
   比較一下3DNow和浮點(diǎn)指令的性能差異,可以看出,3DNow指令集在運(yùn)算速度上要遠(yuǎn)遠(yuǎn)
超過(guò)浮點(diǎn)指令。那么,SSE性能如何呢,它是否有能力同3DNow一拚高低?我想,很難說(shuō)
那一個(gè)更好一些,因?yàn)樗鼈兌加兄芨叩男阅?。不過(guò)單從指令集上看,SSE還是要略勝一
籌的。畢竟是新增了8個(gè)128位的寄存器,而且指令的功能也要強(qiáng)大一些。3DNow使用MMX
指令的寄存器,可以借助MMX指令的強(qiáng)大功能,不必設(shè)計(jì)太多的新功能,不需要操作系
統(tǒng)提供專門的支持,而且口碑頗佳!從流水線的設(shè)計(jì)上看,雙方也是各有所長(zhǎng)。Pentiu
m III每個(gè)時(shí)鐘周期最多可以解碼3條指令,執(zhí)行5個(gè)微操作,它把一些重要的微操作(例
如乘法和加法)分派到不同的端口去執(zhí)行。 3DNow則是在兩條流水線間共享3DNow的執(zhí)行
單元和部分MMX的執(zhí)行單元,所有的3DNow指令都是有兩個(gè)時(shí)鐘周期的延遲,并且完全被
流水線化。
最近,AMD的處理器似乎有了很大的變化,我看過(guò)一些有關(guān)它的64位處理器的資料,也是
添加了一堆寄存器,不過(guò)我沒有仔細(xì)看,畢竟沒有哪個(gè)緣份一睹芳顏。intel公司當(dāng)然也
沒有閑著,它的64位處理器則不能用“變化”二字來(lái)形容了,那簡(jiǎn)直可以說(shuō)是脫胎換骨
,全新的指令,全新的體系!不過(guò),咱們老百姓恐怕不會(huì)在短時(shí)間內(nèi)用上這種處理器,
擁有三百多個(gè)寄存器的CPU肯定會(huì)處于我無(wú)法接受的價(jià)位。這樣也還是有一個(gè)好處的,那
就是SSE指令集在短時(shí)間內(nèi)不會(huì)過(guò)時(shí),畢竟,轉(zhuǎn)移到64位陣營(yíng)還是要經(jīng)歷一個(gè)漫長(zhǎng)的過(guò)程
。而且,在IA-64體系中專門提供了三條指令在32位代碼和64位代碼之間進(jìn)行跳轉(zhuǎn),也就
是說(shuō),你可以在程序中任意使用兩種代碼。
所以,如果你想針對(duì)intel系列的處理器進(jìn)行優(yōu)化的話,就努力學(xué)好SSE吧,在相當(dāng)長(zhǎng)的
時(shí)間里都會(huì)大有用處的。
本文不會(huì)詳細(xì)介紹每一個(gè)SSE指令,只是討論一些重要的,常用的,能夠?qū)π阅墚a(chǎn)生較大
影響的指令。如果你想更全面的了解SSE,請(qǐng)參閱 SSE指令簡(jiǎn)明參考。你可以從中查到每
條SSE指令的功能。
通過(guò)程序來(lái)討論指令的用法是最好的辦法。以前寫過(guò)的兩篇文章,一篇是關(guān)于浮點(diǎn)指令
優(yōu)化的,一篇是關(guān)于3DNow指令優(yōu)化的,這兩篇文章都是使用了矩陣相乘作為例子程序,
因此本文還是以矩陣相乘為例,看一看SSE究竟有什么優(yōu)勢(shì)!它與單純使用浮點(diǎn)指令的程
序相比效率能提高多少!
準(zhǔn)備工作
選擇合適的編譯器
目前我還沒有發(fā)現(xiàn)哪個(gè)編譯器能夠?qū)SE提供內(nèi)聯(lián)支持,據(jù)intel聲稱,它的C++ 編譯器
可以做到,但是,恐怕沒有幾個(gè)人用過(guò)。建議大家使用MASM6.14,它支持SSE和3DNow。
大家可以從本站下載MASM6.14。高級(jí)語(yǔ)言的編譯器也是要有的,我使用的是VC6.0。因?yàn)?br> VC在浮點(diǎn)程序方面比 C++ Builder優(yōu)化的更好,這樣就可以與匯編的優(yōu)化結(jié)果進(jìn)行比較
了。
設(shè)置編譯器
在匯編程序里,應(yīng)該加入偽指令來(lái)指示編譯器支持何種指令集。“.xmm”表示要求編譯
器支持SSE指令集。“.k3d”則是要求編譯器支持3DNow指令集。
VC提供了一些支持,可以自動(dòng)的編譯匯編文件,你可以按照以下步驟進(jìn)行:
在菜單中選擇“Project | Setting”
選中指定的匯編文件(單擊即可)
選中Custom Build頁(yè)
在Commands中輸入:
如果是DEBUG模式,則輸入:
path e:\masm32\bin
ml /c /coff /Zi /FoDEBUG\$(InputName).obj $(InputPath)
如果是RELEASE模式,則輸入:
path e:\masm32\bin
ml /c /coff /FoRELEASE\$(InputName).obj $(InputPath)
在Outputs中輸入:
如果是DEBUG模式,則輸入:
DEBUG\$(InputName).obj
如果是RELEASE模式,則輸入:
RELEASE\$(InputName).obj
如果你的沒有把masm安裝在E盤,則要作相應(yīng)的修改。
學(xué)習(xí)指令
你首先應(yīng)該對(duì)SSE指令有所了解才能更好的閱讀本文。SSE指令集是一個(gè)比較新的體系,
如果你沒有學(xué)過(guò)MMX或者3DNow,還是有一定困難的。在全面優(yōu)化Pentium III一文中對(duì)P
entium III 的體系有比較全面的闡述。
優(yōu)化方針
針對(duì)SSE優(yōu)化還是比較困難的,下面提出一些方法,以供參考:
擺脫高級(jí)語(yǔ)言的桎梏,根據(jù)硬件的特點(diǎn),指令的功能,量體裁衣地設(shè)計(jì)算法。要知道,
匯編語(yǔ)言的算法與高級(jí)語(yǔ)言是有很大的不同的,只有重新設(shè)計(jì)的算法才有可能發(fā)揮出處
理器的最大潛力。
熟練使用一些常用的指令,知道它們的延遲和吞吐量是多少。本文的例子中所用的一些
重要的指令有:ADDPS,MULPS,SHUFPS,MOVSS,MOVAPS。關(guān)于它們的執(zhí)行單元的相關(guān)數(shù)
據(jù)可以查閱處理器執(zhí)行單元列表。
充分利用新增加的八個(gè)寄存器,減小內(nèi)存的壓力;設(shè)計(jì)并行算法,減輕流水線的延遲。

綜合考慮解碼器,流水線,執(zhí)行端口等多方面因素,盡量增強(qiáng)處理器的并行處理的能力
。
舉例詳解
下面的程序是一個(gè)矩陣相乘的函數(shù)。在三維圖形空間變換中,要用到4乘4的浮點(diǎn)矩陣,
而矩陣相乘的運(yùn)算是很常用的。下面的函數(shù)的參數(shù)都是4乘4的浮點(diǎn)矩陣。寫成這種形式
是為了保持比較強(qiáng)的伸縮性。
void MatMul_cpp(float *dest, float *m1, float *m2)
{
    for(int i = 0; i < 4; i ++)
    {
        for(int j = 0; j < 4; j ++)
        {
            dest[i*4+j] =
                m1[i*4+0]*m2[0*4+j] +
                m1[i*4+1]*m2[1*4+j] +
                m1[i*4+2]*m2[2*4+j] +
                m1[i*4+3]*m2[3*4+j] ;
        }
    }
}
VC的優(yōu)化能力是很強(qiáng)的,象上面這樣的比較常規(guī)的算法,你很難做出比它快得多的代碼
。不過(guò)使用SSE以后就不一樣了。下面是一個(gè)匯編函數(shù),使用SSE 指令進(jìn)行計(jì)算。注意,
這個(gè)函數(shù)只能運(yùn)行于32位的環(huán)境中。“.xmm”指示編譯器使用SSE指令集進(jìn)行編譯。
函數(shù)的C語(yǔ)言原型是這樣的:
extern "C"
{
void __stdcall MatMul_xmm(float *dest, float *m1, float *m2);
}
對(duì)于一些不太常用匯編語(yǔ)言編程的朋友來(lái)說(shuō),下面的程序可能比較難于理解。我將對(duì)一
些常識(shí)性的東西做一下簡(jiǎn)單介紹。
在C語(yǔ)言中,代碼段都是以“_TEXT”作為段名的。“use32”告訴編譯器將代碼編譯為3
2位。
有些人看到“_MatMul_xmm@12”這個(gè)函數(shù)名以后可能會(huì)產(chǎn)生疑問(wèn)。其實(shí)這只是遵循了VC
所采用的命名規(guī)范。在VC中,所有標(biāo)志為“__stdcall” 調(diào)用的,采用“C”鏈接的函數(shù)
都要加下劃線作為前綴,并且加上“@N”作為后綴,其中,“N”為參數(shù)的字節(jié)數(shù)。注意
,上面的函數(shù)是采用“C”鏈接的,如果是“C++”鏈接,命名規(guī)范就太復(fù)雜了。如果你
使用的是C++ Builder,命名規(guī)范就十分簡(jiǎn)單了,照搬函數(shù)名就行了。不同的調(diào)用規(guī)范將
采用不同的命名方法,即使對(duì)相同的調(diào)用規(guī)范,不同的編譯器也不一定兼容。有一種調(diào)
用格式是每一個(gè)C++編譯器都支持并且兼容的,那就是“__cdecl”。
各種調(diào)用格式所采用的堆棧操作也不太一樣。使用“__stdcall”時(shí),參數(shù)從右向左依次
入棧,參數(shù)的彈出需要函數(shù)自己來(lái)處理。這種做法和“__cdecl” 調(diào)用方式不太一樣,
“__cdecl”的參數(shù)彈出需要調(diào)用者來(lái)處理。現(xiàn)在很流行的一種調(diào)用格式是“__fastcal
l”,也就是寄存器調(diào)用。這種調(diào)用方式通過(guò)寄存器“EAX”,“ECX”,“EDX”傳遞參
數(shù),不過(guò)很可惜,這種調(diào)用也不是在各個(gè)編譯器中兼容的。Inprise在C++ Builder中提
供了一個(gè)關(guān)鍵字“__msfastcall” 用來(lái)和微軟兼容,如果你采用這種調(diào)用規(guī)范就可以在
多個(gè)編譯器中正常調(diào)用了。不過(guò)還有一件事讓人很受打擊,VC沒有對(duì)“__fastcall”提
供很好的優(yōu)化,使用這種調(diào)用反而會(huì)降低效率。
并不是所有的寄存器都能夠隨意使用的,多數(shù)32位寄存器都要先保存的。你可以不必保
存的32位寄存器只有三個(gè)----“EAX”,“ECX”,“EDX”,其它的就只好“PUSH”,“
POP”了。另外,浮點(diǎn)堆棧寄存器是不必保存的;MMX 寄存器和浮點(diǎn)堆棧共享,也是不必
保存的;XMM寄存器不必保存。
很多SSE指令都會(huì)加上“ps”或“ss”后綴。“ps”表示“Packed Single-FP”,即打包
的浮點(diǎn)數(shù),帶這種后綴的指令通常是一次性對(duì)四個(gè)數(shù)進(jìn)行操作的。“ss” 表示“Scala
r Single-FP”,帶這種后綴的指令通常是對(duì)最低位的單精度數(shù)進(jìn)行操作的。
下面這個(gè)匯編函數(shù)是一行一行計(jì)算的,咱們先用類似于C的語(yǔ)法簡(jiǎn)述一下第一行的計(jì)算過(guò)
程:
    xmm0 = m1[0],m1[0],m1[0],m1[0];
    xmm1 = m1[1],m1[1],m1[1],m1[1];
    xmm2 = m1[2],m1[2],m1[2],m1[2];
    xmm3 = m1[3],m1[3],m1[3],m1[3];
    xmm4 = m2[0],m2[1],m2[2],m2[3];
    xmm5 = m2[4],m2[5],m2[6],m2[7];
    xmm6 = m2[8],m2[9],m2[10],m2[11];
    xmm7 = m2[12],m2[13],m2[14],m2[15];
    xmm0 *= xmm4;
    xmm1 *= xmm5;
    xmm2 *= xmm6;
    xmm3 *= xmm7;
    xmm1 += xmm0;
    xmm2 += xmm1;
    xmm3 += xmm2;
    dst[0],dst[1],dst[2],dst[3] = xmm3;
上面的代碼可讀性還是比較好的,因?yàn)橹贿M(jìn)行了第一行的計(jì)算。實(shí)際運(yùn)算中,為了增強(qiáng)
并行度,為了減小指令的延遲,實(shí)際上是兩行并行計(jì)算的。而且,運(yùn)算過(guò)程并不是象算
法描述那樣寫得那么有規(guī)律。
        .686p
        .xmm
        .model flat
_TEXT segment public use32 'CODE'
public _MatMul_xmm@12
_MatMul_xmm@12 proc
;;parameters
retaddress = 0
dst = retaddress+4
m1 = dst+4
m2 = m1+4
        mov          edx,     [esp+m1]
        mov          ecx,     [esp+m2]
        mov          eax,     [esp+dst]
        movss        xmm0,    [edx+16*0+4*0]   ;讀入第一行的數(shù)據(jù)
        movaps       xmm4,    [ecx+16*0]
        movss        xmm1,    [edx+16*0+4*1]
        shufps       xmm0,    xmm0,    00h
        movaps       xmm5,    [ecx+16*1]
        movss        xmm2,    [edx+16*0+4*2]
        shufps       xmm1,    xmm1,    00h
        mulps        xmm0,    xmm4
        movaps       xmm6,    [ecx+16*2]
        mulps        xmm1,    xmm5
        movss        xmm3,    [edx+16*0+4*3]
        shufps       xmm2,    xmm2,    00h
        movaps       xmm7,    [ecx+16*3]
        shufps       xmm3,    xmm3,    00h
        mulps        xmm2,    xmm6
        addps        xmm1,    xmm0
        movss        xmm0,    [edx+16*1+4*0]   ;讀入第二行的數(shù)據(jù)
        mulps        xmm3,    xmm7
        shufps       xmm0,    xmm0,    00h
        addps        xmm2,    xmm1
        movss        xmm1,    [edx+16*1+4*1]
        mulps        xmm0,    xmm4
        shufps       xmm1,    xmm1,    00h
        addps        xmm3,    xmm2
        movss        xmm2,    [edx+16*1+4*2]
        mulps        xmm1,    xmm5
        shufps       xmm2,    xmm2,    00h
        movaps       [eax+16*0],    xmm3
        movss        xmm3,    [edx+16*1+4*3]
        mulps        xmm2,    xmm6
        shufps       xmm3,    xmm3,    00h
        addps        xmm1,    xmm0
        movss        xmm0,    [edx+16*2+4*0]   ;讀入第三行的數(shù)據(jù)
        mulps        xmm3,    xmm7
        shufps       xmm0,    xmm0,    00h
        addps        xmm2,    xmm1
        movss        xmm1,    [edx+16*2+4*1]
        mulps        xmm0,    xmm4
        shufps       xmm1,    xmm1,    00h
        addps        xmm3,    xmm2
        movss        xmm2,    [edx+16*2+4*2]
        mulps        xmm1,    xmm5
        shufps       xmm2,    xmm2,    00h
        movaps       [eax+16*1],    xmm3
        movss        xmm3,    [edx+16*2+4*3]
        mulps        xmm2,    xmm6
        shufps       xmm3,    xmm3,    00h
        addps        xmm1,    xmm0
        movss        xmm0,    [edx+16*3+4*0]   ;讀入第四行的數(shù)據(jù)
        mulps        xmm3,    xmm7
        shufps       xmm0,    xmm0,    00h
        addps        xmm2,    xmm1
        movss        xmm1,    [edx+16*3+4*1]
        mulps        xmm0,    xmm4
        shufps       xmm1,    xmm1,    00h
        addps        xmm3,    xmm2
        movss        xmm2,    [edx+16*3+4*2]
        mulps        xmm1,    xmm5
        shufps       xmm2,    xmm2,    00h
        movaps       [eax+16*2],    xmm3
        movss        xmm3,    [edx+16*3+4*3]
        mulps        xmm2,    xmm6
        shufps       xmm3,    xmm3,    00h
        addps        xmm1,    xmm0
        mulps        xmm3,    xmm7
        addps        xmm2,    xmm1
        addps        xmm3,    xmm2
        movaps       [eax+16*3],    xmm3
        ret          12
_MatMul_xmm@12 endp
_TEXT ends
        end
上面的代碼幾乎沒有加什么注釋,只是在讀入每行第一個(gè)數(shù)據(jù)時(shí)作了標(biāo)記。因?yàn)?,SSE
的指令可讀性還是比較好的,除了要加上一些后綴以外,它們和普通的整數(shù)運(yùn)算指令很
相似。
一些關(guān)鍵性的指令有必要解釋一下:
movss和movaps:
movss是將一個(gè)單精度數(shù)傳輸?shù)絰mm寄存器的低32位,而movaps則是一次性向寄存器中寫
入四個(gè)單精度數(shù)。也許有些人會(huì)認(rèn)為movaps效率更高一些,其實(shí)并不一定是這樣。從處
理器執(zhí)行單元列表中,你可以查到這些指令的延遲。如果都是從寄存器中讀取數(shù)據(jù),兩
個(gè)指令的延遲是一樣的。如果是從內(nèi)存中讀取數(shù)據(jù),movss只有一個(gè)時(shí)鐘周期的延遲,而
movaps卻有四個(gè)時(shí)鐘周期的延遲。
上面的匯編代碼混合使用了這兩條指令。那么,應(yīng)該在什么時(shí)候選擇哪一條指令呢?這
要看你對(duì)數(shù)據(jù)的需求了。如果你希望能夠盡快地使用數(shù)據(jù),就應(yīng)當(dāng)首選movss,因?yàn)樗鼛?br> 乎能夠讓你立即使用數(shù)據(jù)。如果你并不急于使用某些數(shù)據(jù),只是想先把它讀入寄存器,
那么毫無(wú)疑問(wèn)movaps是你的最佳選擇。 movaps使用端口2讀取數(shù)據(jù),如果在它執(zhí)行完畢
之前你不去使用它的數(shù)據(jù),這條指令的實(shí)際延遲就只有一個(gè)時(shí)鐘周期??紤]到處理器能
夠在5個(gè)端口并行執(zhí)行微操作,那么這條指令的延遲可能還不到一個(gè)時(shí)鐘周期。
從上面的代碼中,你可以看到,每一條movaps指令和它的相關(guān)指令之間都至少插入了四
條指令,這樣可以基本上避免延遲。
雖然movss指令只有一個(gè)時(shí)鐘周期的延遲,但是這也并不意味著你可以把這條指令和它的
相關(guān)指令寫在一起,因?yàn)檫@有可能會(huì)影響處理器的并行度。雖然 Pentium III有著強(qiáng)大
的亂序執(zhí)行的能力,可是這畢竟是不太保險(xiǎn)的,還是自己動(dòng)手,豐衣足食吧。
SHUFPS
這是一條可以將操作數(shù)打亂順序的指令。這一條指令有很多種用法,它根據(jù)常量參數(shù)的
不同執(zhí)行不同的功能。本文中只使用了一種用法:
    shufps      xmmreg,  xmmreg,  00h
這條指令的作用是把某個(gè)寄存器的最低位的單精度數(shù)傳輸?shù)皆摷拇嫫鞯钠渌齻€(gè)部分。

在某些時(shí)候,shufps和unpcklps(或unpckhps)可以執(zhí)行相同的功能。這時(shí),推薦使用
shufps,因?yàn)檫@條指令有兩個(gè)時(shí)鐘周期的延遲。unpcklps和unpckhps 都是有三個(gè)時(shí)鐘周
期的延遲。
ADDPS和MULPS
這兩條指令是很重要的計(jì)算指令,有必要弄清楚它們的執(zhí)行情況。
addps有4個(gè)時(shí)鐘周期的延遲,mulps有5個(gè)時(shí)鐘周期的延遲,我們應(yīng)該根據(jù)這些數(shù)據(jù)考慮
清楚,究竟在它們的相關(guān)代碼中插入多少條指令。
這兩條指令都是每?jī)蓚€(gè)時(shí)鐘周期才允許執(zhí)行一次,如果你把相同的兩條這樣的指令寫在
一起,第二條指令就有可能被延誤一個(gè)時(shí)鐘周期。應(yīng)該插入一些其它指令來(lái)掩蓋這段延
遲。
mulps在端口0執(zhí)行,addps在端口1執(zhí)行,如果你的代碼把乘法和加法指令寫在一起,它
們會(huì)被分配到不同的端口并行執(zhí)行,這比只有一條流水線的FPU要高效的多。
優(yōu)化思路:
下面將解釋一下上面代碼的優(yōu)化思路。
打亂指令
在算法描述中,各條操作寫得非常有規(guī)律,但是在真正編程的時(shí)候卻不是這樣。為了保
證流水線的流暢運(yùn)作,就要把相關(guān)的代碼分離開來(lái),盡量避免或減輕指令的延遲。這樣
就要打亂指令,在兩條相關(guān)指令之間插入一些其它的指令,同時(shí)也要考慮指令之間是否
存在資源的競(jìng)爭(zhēng)。
并行算法
多個(gè)數(shù)據(jù)并行計(jì)算是解決指令延遲問(wèn)題的有效方法。我們不能傻傻地等待一條指令的計(jì)
算結(jié)果,而是要在等待的過(guò)程中進(jìn)行其它數(shù)據(jù)的計(jì)算。在上面程序的算法中,每當(dāng)寄存
器有了空閑,就馬上從內(nèi)存中讀入新的數(shù)據(jù),盡量保證有兩組數(shù)據(jù)在寄存器中并行計(jì)算
。
內(nèi)存訪問(wèn)
訪問(wèn)內(nèi)存的指令不要過(guò)于密集,這一方面可以減輕對(duì)帶寬的需求,另一方面也會(huì)提高解
碼的效率。訪問(wèn)內(nèi)存的指令至少有兩個(gè)微操作,這樣的指令只能每個(gè)時(shí)鐘周期解碼一條
,而Pentium III的解碼極限可是每個(gè)時(shí)鐘周期三條指令啊。為了提高處理器的并行度,
有必要在內(nèi)存訪問(wèn)指令上下功夫。在我的代碼中,內(nèi)存訪問(wèn)指令的排布還是比較有規(guī)律
的,差不多是每隔三條指令訪問(wèn)一次內(nèi)存。當(dāng)然,在計(jì)算第一行數(shù)據(jù)時(shí),因?yàn)橐x取一
些初始化的數(shù)據(jù),內(nèi)存訪問(wèn)比后面的代碼要頻繁。
靈活性
矩陣的運(yùn)算是一行一行進(jìn)行的,每一行數(shù)據(jù)只被讀取一次。這就意味著,我們可以把運(yùn)
算結(jié)果保存在任何一個(gè)矩陣?yán)铮幢4嬖趍1或者m2中,因?yàn)檫@兩個(gè)矩陣中的數(shù)據(jù)已經(jīng)不
會(huì)被再次讀取了,也就不用擔(dān)心破壞數(shù)據(jù)。這種靈活性可以是我們輕而易舉地完成矩陣
左乘或者右乘的代碼。在Direct3D中,空間變換是按照如下方式進(jìn)行計(jì)算的:
在進(jìn)行多次變換時(shí),只要在原有的矩陣上右乘一個(gè)變換矩陣就可以了。下面的代碼就是
這樣的一個(gè)例子:
MatMul_xmm(m1, m1, m2);
如果使用高級(jí)語(yǔ)言來(lái)實(shí)現(xiàn)恐怕就要麻煩一些,你要使用一些中間變量,程序如下所示:

void MatMul_Right_cpp(float *dest, float *m)
{
    float tmp[16];
    MatMul_cpp(tmp, dest, m)
    memcpy(dest, tmp, 16*4);
}
 

Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1270109

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多