久久亚洲成a人片熟女精品色一区二区三区|国产精品视频第一精品视频|av天堂热无码手机版|亚洲?v无码久久无遮挡|国产精品偷伦视频免费观看国产|麻豆国产自产精品丰满熟妇|av无码av不卡一区二区|久久亚洲精品中文字

ARTICLE DETAIL

資訊詳情

深耕商務(wù)建站與企業(yè)官網(wǎng)運(yùn)營(yíng)的一線實(shí)戰(zhàn)洞察。

數(shù)據(jù)驅(qū)動(dòng)+SIMD:粒子系統(tǒng)內(nèi)存布局優(yōu)化與百倍性能提升實(shí)戰(zhàn)

數(shù)據(jù)驅(qū)動(dòng)+SIMD:粒子系統(tǒng)內(nèi)存布局優(yōu)化與百倍性能提升實(shí)戰(zhàn) 一個(gè)朋友找我調(diào)過(guò)一個(gè)工業(yè)仿真系統(tǒng)里的粒子更新邏輯。從算法上看它簡(jiǎn)單到不能再簡(jiǎn)單——一個(gè)for循環(huán)每個(gè)粒子做一次牛頓力學(xué)更新整體復(fù)雜度就是標(biāo)準(zhǔn)的O(n)。但跑起來(lái)就是慢50萬(wàn)粒子一幀更新要120毫秒CPU占用還忽高忽低厲害的時(shí)候幀率直接掉到十幾。我打開性能剖析一看cache-misses高得離譜branch-misses快20%了。說(shuō)實(shí)話這類問(wèn)題我在不止一個(gè)項(xiàng)目里見過(guò)性能瓶頸根本不在算法本身而在你壓根沒(méi)用數(shù)據(jù)驅(qū)動(dòng)的方式去組織內(nèi)存。這篇文章我會(huì)用這個(gè)真實(shí)案例完整拆解一遍從對(duì)象思維到數(shù)據(jù)驅(qū)動(dòng)、配合SIMD向量化做內(nèi)存布局優(yōu)化最后拿到工業(yè)級(jí)百倍性能提升的全過(guò)程。內(nèi)容不挑平臺(tái)搞游戲引擎、圖像處理、工業(yè)仿真或者高頻交易系統(tǒng)的朋友應(yīng)該都能從中找到能直接抄作業(yè)的東西。1. 為什么性能瓶頸在內(nèi)存而不在算法數(shù)據(jù)驅(qū)動(dòng)設(shè)計(jì)的第一課很多人一想到性能優(yōu)化第一反應(yīng)就是換算法、減復(fù)雜度。但在現(xiàn)代CPU上一個(gè)更普遍的現(xiàn)實(shí)是你的數(shù)據(jù)根本來(lái)不及喂給CPU算。不理解這一點(diǎn)后面所有優(yōu)化都容易跑偏。1.1 從一段“看著沒(méi)毛病”的粒子系統(tǒng)說(shuō)起先看當(dāng)時(shí)那段代碼的簡(jiǎn)化版。結(jié)構(gòu)體是一個(gè)標(biāo)準(zhǔn)的Particle對(duì)象里面放了位置、速度、質(zhì)量、生命周期、存活標(biāo)記然后扔進(jìn)std::vectorParticle里挨個(gè)遍歷struct Particle { float x, y, z; float vx, vy, vz; float mass; float life; bool alive; }; class ParticleSystem { public: void update(float dt) { for (Particle p : m_particles) { if (!p.alive) continue; p.vx (f_x / p.mass) * dt; p.vy (f_y / p.mass) * dt; p.vz (f_z / p.mass) * dt; p.x p.vx * dt; p.y p.vy * dt; p.z p.vz * dt; p.life - dt; if (p.life 0.0f) p.alive false; } } private: std::vectorParticle m_particles; };如果你只從“代碼規(guī)范”的角度看這段代碼沒(méi)有任何毛病封裝合理、邏輯清晰、甚至已經(jīng)加了“死亡粒子跳過(guò)”的優(yōu)化。但實(shí)際跑起來(lái)它就是慢。為什么因?yàn)槟愕腃PU從來(lái)不會(huì)真的按“一個(gè)對(duì)象一個(gè)對(duì)象”去讀數(shù)據(jù)。它每次從內(nèi)存拿數(shù)據(jù)是64字節(jié)、64字節(jié)地拿這64字節(jié)叫做一個(gè)cache line。對(duì)象在這個(gè)數(shù)組里挨個(gè)排但每個(gè)對(duì)象你還塞了一個(gè)bool又因?yàn)閷?duì)齊規(guī)則每個(gè)對(duì)象實(shí)際占40字節(jié)左右。一個(gè)64字節(jié)的緩存行放1個(gè)對(duì)象多一點(diǎn)。更麻煩的是當(dāng)粒子開始死亡alive字段變成false的粒子還留在數(shù)組中間遍歷時(shí)經(jīng)常是“讀一個(gè)活的跳一個(gè)死的再讀一個(gè)活的”大量緩存行加載上來(lái)真正用到的數(shù)據(jù)不到一半。問(wèn)題就這么來(lái)了。1.2 CPU存儲(chǔ)層級(jí)與“緩存錢罐子”要徹底理解這個(gè)慢得先看一張現(xiàn)代CPU的存儲(chǔ)層級(jí)賬本。速度從快到慢大致是寄存器、L1緩存、L2緩存、L3緩存、內(nèi)存。它們之間的延遲差異不是一點(diǎn)點(diǎn)而是數(shù)量級(jí)的差距。存儲(chǔ)層級(jí)典型延遲一個(gè)極其粗略的類比寄存器不到1ns口袋里掏鑰匙L1緩存1ns左右手邊的文件抽屜L2緩存4ns左右跑到隔壁房間拿L3緩存12ns左右下樓去車?yán)锬脙?nèi)存80ns以上出門跑一趟便利店你可以把優(yōu)化代碼理解為你寫的每一行算法CPU真正計(jì)算的時(shí)間其實(shí)都很快大部分時(shí)間都耗在“從便利店把東西搬回來(lái)”這一步。如果你的程序訪問(wèn)內(nèi)存的方式是東一榔頭西一棒子緩存行加載上來(lái)只能用三分之一那就是在大把大把浪費(fèi)內(nèi)存帶寬。更形象點(diǎn)說(shuō)內(nèi)存對(duì)你寫的循環(huán)是無(wú)情的它只認(rèn)地址不認(rèn)對(duì)象。誰(shuí)和誰(shuí)在地址上挨得近誰(shuí)能被一起加載進(jìn)緩存誰(shuí)的性能就好。這就是數(shù)據(jù)驅(qū)動(dòng)設(shè)計(jì)最底層的一句行話——“面向緩存編程”。1.3 對(duì)象思維是怎么把性能拖垮的面向?qū)ο蟊旧頉](méi)有錯(cuò)但盲目用對(duì)象組織一切熱數(shù)據(jù)有三個(gè)隱藏成本。第一個(gè)是數(shù)據(jù)離散。對(duì)象把每個(gè)粒子的所有字段打包在一起看似聚合了“一個(gè)粒子”的信息但如果一個(gè)循環(huán)只關(guān)心位置和速度你去把質(zhì)量、生命周期、存活標(biāo)志一起讀上來(lái)就是白白浪費(fèi)帶寬。信息量大不是問(wèn)題問(wèn)題是加載粒度是緩存行你只能整塊整塊地拿。第二個(gè)是分支預(yù)測(cè)懲罰。當(dāng)數(shù)組里有大量死亡粒子時(shí)那個(gè)if (!p.alive)的分支就變成一個(gè)非常難預(yù)測(cè)的分支。CPU往流水線里塞了一堆指令賭你下一次跳過(guò)還是執(zhí)行賭錯(cuò)了就要把流水線沖洗掉重來(lái)——這個(gè)懲罰比緩存未命中還要隱蔽有時(shí)候占比高得嚇人。第三個(gè)是SIMD無(wú)法展開。這章先點(diǎn)到為止現(xiàn)代CPU支持一條指令同時(shí)算4個(gè)float或者8個(gè)float叫SIMD。但前提是你的數(shù)據(jù)在內(nèi)存里是緊密排列的同類型數(shù)據(jù)。如果你的是一個(gè)Particle對(duì)象數(shù)組里面隔一個(gè)結(jié)構(gòu)體才有一個(gè)float地址SIMD想發(fā)力也發(fā)不上來(lái)。所以對(duì)象思維最大的問(wèn)題不是“類”這個(gè)抽象而是它默認(rèn)把“邏輯上的內(nèi)聚”當(dāng)成了“內(nèi)存上的內(nèi)聚”。而CPU真正在乎的是后者。下面就從內(nèi)存布局的角度開始做第一輪重構(gòu)。2. 內(nèi)存布局優(yōu)化AoS到SoA結(jié)構(gòu)體數(shù)組與數(shù)組結(jié)構(gòu)體的本質(zhì)區(qū)別內(nèi)存布局優(yōu)化最核心的一步就是把數(shù)據(jù)從“以對(duì)象為中心”的組織方式翻轉(zhuǎn)為“以字段為中心”的組織方式。技術(shù)上管這兩種布局叫AoSArray of Structures對(duì)象數(shù)組和SoAStructure of Arrays數(shù)組對(duì)象。2.1 AoS與SoA的取舍各自解決什么問(wèn)題先看兩種布局的代碼對(duì)比。AoS原本的做法struct Particle { float x, y, z; float vx, vy, vz; float mass; float life; bool alive; }; std::vectorParticle particles;SoA數(shù)據(jù)驅(qū)動(dòng)后的做法struct ParticleSystem { std::vectorfloat x, y, z; std::vectorfloat vx, vy, vz; std::vectorfloat mass; std::vectorfloat life; std::vectoruint8_t alive; size_t alive_count 0; };AoS的好處是“一個(gè)對(duì)象的所有東西都在旁邊”cache局部性對(duì)單對(duì)象操作很友好代碼寫起來(lái)也自然。但對(duì)“批量遍歷同一字段”這種典型熱循環(huán)它完全不對(duì)路。SoA則把所有x放在一起、所有y放在一起、所有vx放在一起。以遍歷50萬(wàn)個(gè)粒子更新位置為例AoS版本讀一個(gè)粒子要帶上40字節(jié)里你并不關(guān)心的質(zhì)量、生命等而SoA版本可以只把x數(shù)組整個(gè)順序讀一遍每一塊緩存行都裝滿了下一個(gè)粒子的x利用率接近100%。2.2 動(dòng)手重構(gòu)粒子組件陣列這輪重構(gòu)我建議直接照著一個(gè)原則來(lái)把一個(gè)對(duì)象的所有字段拆成平行的數(shù)組數(shù)組下標(biāo)就是對(duì)象的編號(hào)。這個(gè)下標(biāo)你可以理解為“實(shí)體ID”或者“粒子ID”它不再需要存在內(nèi)存里因?yàn)檠h(huán)變量本身就是ID。改造后的更新邏輯長(zhǎng)這樣void update(float dt, float f_x, float f_y, float f_z) { for (size_t i 0; i alive_count; i) { float inv_mass 1.0f / mass[i]; vx[i] f_x * inv_mass * dt; vy[i] f_y * inv_mass * dt; vz[i] f_z * inv_mass * dt; x[i] vx[i] * dt; y[i] vy[i] * dt; z[i] vz[i] * dt; life[i] - dt; alive[i] (life[i] 0.0f); } }看到區(qū)別了嗎這里同時(shí)完成了幾個(gè)動(dòng)作if分支從熱循環(huán)里消失了。甚至不需要在循環(huán)里判斷死活循環(huán)只跑前alive_count個(gè)。每個(gè)數(shù)組都是純float序列連續(xù)地址順序訪問(wèn)緩存友好度直接拉滿。為下一步SIMD鋪好了路——每個(gè)數(shù)組都是同類型的連續(xù)內(nèi)存塊。有朋友會(huì)問(wèn)那死掉的粒子怎么辦把它們直接留在原地再把末尾的活粒子搬過(guò)來(lái)覆蓋叫swap-and-pop俗稱“借尸還魂”。因?yàn)榱W又g沒(méi)有邏輯順序要求這是工業(yè)界最常見的做法void swap_remove(size_t idx) { --alive_count; if (idx ! alive_count) { std::swap(x[idx], x[alive_count]); std::swap(y[idx], y[alive_count]); std::swap(z[idx], z[alive_count]); std::swap(vx[idx], vx[alive_count]); std::swap(vy[idx], vy[alive_count]); std::swap(vz[idx], vz[alive_count]); std::swap(mass[idx], mass[alive_count]); std::swap(life[idx], life[alive_count]); } }這樣做的直接效果是數(shù)組前alive_count個(gè)永遠(yuǎn)是活粒子更新循環(huán)不需要任何分支CPU的流水線可以全速推進(jìn)。2.3 對(duì)齊、填充與分配器細(xì)節(jié)從AoS切換到SoA之后另一個(gè)必須考慮的點(diǎn)是內(nèi)存對(duì)齊。普通std::vectorfloat分配的起始地址通常對(duì)齊到16字節(jié)這對(duì)標(biāo)量代碼綽綽有余但后面要用AVX2的話必須保證32字節(jié)對(duì)齊。C17里可以直接用aligned_alloc自定義對(duì)齊分配器或者干脆先手動(dòng)實(shí)現(xiàn)一個(gè)簡(jiǎn)單的float* aligned_alloc_and_init(size_t n) { void* ptr std::aligned_alloc(32, n * sizeof(float)); return static_castfloat*(ptr); }還有一個(gè)很容易被忽略的細(xì)節(jié)結(jié)構(gòu)體字段重排減少padding。雖然在SoA里那個(gè)大結(jié)構(gòu)體只是若干個(gè)容器但如果你在業(yè)務(wù)代碼里還保留了少量“小結(jié)構(gòu)體”記得把同類型字段排在一起。比如// 差bool夾在float中間白白多出3字節(jié)padding struct Item { float value; bool valid; float count; }; // 好同類型靠攏編譯器不額外補(bǔ)洞 struct Item { float value; float count; bool valid; };低效的布局會(huì)讓緩存行承“沙子”多過(guò)承“水”工業(yè)級(jí)代碼里這些小錢也要摳。2.4 第一輪收益為什么提升了20倍這輪重構(gòu)做完我先跑了一遍perf stat對(duì)比基線數(shù)據(jù)。同一臺(tái)機(jī)器、同樣50萬(wàn)個(gè)粒子、同樣物理參數(shù)AoS版本更新一次平均120ms左右SoA版本降到了大約8ms。算下來(lái)15到20倍的提升。這個(gè)數(shù)字怎么來(lái)的拆開看大概是三部分緩存命中率大幅提升順序讀多個(gè)純float數(shù)組和“跳著讀40字節(jié)對(duì)象穿插bool”相比有效內(nèi)存流量少了約3到5倍。分支預(yù)測(cè)懲罰消失原來(lái)那個(gè)if (!p.alive) continue在粒子死亡率接近一半時(shí)幾乎每次都是50%概率猜錯(cuò)流水線沖洗成本極高。把活躍粒子集中到數(shù)組前段后循環(huán)沒(méi)有任何分支這部分收益非??捎^。swap-and-pop帶來(lái)的連續(xù)密度收益活粒子全部擠在一起cache line利用率接近100%。到這里數(shù)據(jù)布局已經(jīng)為最終速度打下了地基。但只有地基還不夠真正把CPU的算力發(fā)揮出來(lái)的是下一層的SIMD向量化。3. SIMD向量化實(shí)戰(zhàn)讓CPU一次算八個(gè)float第一輪優(yōu)化靠的是“少搬數(shù)據(jù)”SIMD則是“一次搬更多、算更多”。它不是玄學(xué)而是現(xiàn)代CPU早就給你準(zhǔn)備好的并行能力。3.1 SIMD能做什么一條指令處理8個(gè)float先解釋一下SIMDSingle Instruction, Multiple Data。它的思想很簡(jiǎn)單普通加法學(xué)的是“兩個(gè)float相加”SIMD一條指令能做“兩組8個(gè)float對(duì)應(yīng)相加”等于把4個(gè)或8個(gè)計(jì)算任務(wù)打包成一次執(zhí)行。拿AVX2指令集舉例它有32個(gè)256位寄存器YMM寄存器每個(gè)可以塞8個(gè)32位float也就是一條指令處理8個(gè)粒子。類似地SSE是128位寄存器一次4個(gè)float。你寫普通循環(huán)的時(shí)候CPU理論上也能做到這一點(diǎn)但它需要你的代碼滿足一堆特殊條件才行。3.2 編譯器自動(dòng)向量化的坑別指望它“幫你搞定”很多文章告訴你“開-O3 -marchnative編譯器會(huì)自動(dòng)向量化?!边@話對(duì)了一半。它能幫你的是識(shí)別最簡(jiǎn)單的循環(huán)但老實(shí)的編譯器有很多“不敢做”的事。指針別名問(wèn)題編譯器沒(méi)法證明寫x[i]不會(huì)影響到別處的vx[i]萬(wàn)一你的指針是重疊的呢所以它寧可保守地一條條算。循環(huán)里帶分支雖然新版本編譯器支持帶掩碼的SIMD指令但判斷邏輯越復(fù)雜它越容易放棄。浮點(diǎn)運(yùn)算順序浮點(diǎn)不滿足結(jié)合律。(a b) c嚴(yán)格來(lái)說(shuō)不等于a (b c)。編譯器默認(rèn)不敢亂重排除非你允許它放寬精度。數(shù)據(jù)不是緊密同類型數(shù)組AoS布局本身就讓編譯器無(wú)從下手它總不能為你的Particle對(duì)象數(shù)組每條都做gather加載吧。所以我的建議是熱循環(huán)里不要依賴自動(dòng)向量化關(guān)鍵路徑直接手寫intrinsics。手動(dòng)寫的好處是每一步算什么都由你把控接受不了的編譯器限制你也能繞過(guò)去。3.3 手寫Intrinsics核心循環(huán)改寫全程下面這段是改造后的AVX2版本更新內(nèi)核。假設(shè)我們已經(jīng)用swap-and-pop維護(hù)好了活躍粒子并且數(shù)組長(zhǎng)度是8的倍數(shù)或者尾部用標(biāo)量兜底#include immintrin.h void update_simd( float* __restrict x, float* __restrict y, float* __restrict z, float* __restrict vx, float* __restrict vy, float* __restrict vz, float* __restrict inv_mass, size_t n, float dt, float f_x, float f_y, float f_z) { const __m256 dtv _mm256_set1_ps(dt); const __m256 fxv _mm256_set1_ps(f_x); const __m256 fyv _mm256_set1_ps(f_y); const __m256 fzv _mm256_set1_ps(f_z); for (size_t i 0; i 8 n; i 8) { __m256 inv_m _mm256_load_ps(inv_mass[i]); __m256 vx0 _mm256_load_ps(vx[i]); __m256 vy0 _mm256_load_ps(vy[i]); __m256 vz0 _mm256_load_ps(vz[i]); __m256 ax _mm256_mul_ps(fxv, inv_m); __m256 ay _mm256_mul_ps(fyv, inv_m); __m256 az _mm256_mul_ps(fzv, inv_m); vx0 _mm256_add_ps(vx0, _mm256_mul_ps(ax, dtv)); vy0 _mm256_add_ps(vy0, _mm256_mul_ps(ay, dtv)); vz0 _mm256_add_ps(vz0, _mm256_mul_ps(az, dtv)); _mm256_store_ps(vx[i], vx0); _mm256_store_ps(vy[i], vy0); _mm256_store_ps(vz[i], vz0); __m256 x0 _mm256_load_ps(x[i]); __m256 y0 _mm256_load_ps(y[i]); __m256 z0 _mm256_load_ps(z[i]); x0 _mm256_add_ps(x0, _mm256_mul_ps(vx0, dtv)); y0 _mm256_add_ps(y0, _mm256_mul_ps(vy0, dtv)); z0 _mm256_add_ps(z0, _mm256_mul_ps(vz0, dtv)); _mm256_store_ps(x[i], x0); _mm256_store_ps(y[i], y0); _mm256_store_ps(z[i], z0); } // 尾部不足8個(gè)的部分退化為標(biāo)量循環(huán) for (size_t i n ~size_t(7); i n; i) { float inv 1.0f / inv_mass[i]; vx[i] f_x * inv * dt; vy[i] f_y * inv * dt; vz[i] f_z * inv * dt; x[i] vx[i] * dt; y[i] vy[i] * dt; z[i] vz[i] * dt; } }幾個(gè)容易寫錯(cuò)的點(diǎn)__restrict必須加上。它告訴編譯器“我保證這些指針互不重疊你可以大膽優(yōu)化?!辈患拥脑捑幾g器可能會(huì)在寄存器分配時(shí)插入多余的load/store。_mm256_load_ps要求地址32字節(jié)對(duì)齊否則直接崩潰。這也就是前面強(qiáng)調(diào)aligned_alloc的原因。我把mass換成了inv_mass即預(yù)先算好質(zhì)量的倒數(shù)。因?yàn)镾IMD里除法遠(yuǎn)比乘法昂貴能省則省。3.4 SIMD實(shí)踐中的精度、除法與掩碼問(wèn)題這里有幾個(gè)工業(yè)級(jí)項(xiàng)目里必須面對(duì)的現(xiàn)實(shí)問(wèn)題。第一個(gè)是精度。SIMD的浮點(diǎn)運(yùn)算順序和標(biāo)量版不同結(jié)果會(huì)有細(xì)微差異。比如vx ax*dt這個(gè)表達(dá)式編譯器可能重新組合成(ax*dt)vx最后一位小數(shù)可能不同。如果你是在做物理仿真或者科學(xué)計(jì)算這種差異可能需要單獨(dú)評(píng)估。保守方案是SIMD版本做一個(gè)開關(guān)關(guān)鍵路徑可回退標(biāo)量版。第二個(gè)是除法。上面已經(jīng)提到div_ps是慢指令能轉(zhuǎn)成乘法就轉(zhuǎn)成乘法。但要注意預(yù)計(jì)算inv_mass 1.0f / mass的時(shí)候如果mass為0除零情況要提前處理。第三個(gè)是死亡粒子的掩碼處理。如果不想把活躍粒子單獨(dú)搬出來(lái)也可以直接在SIMD循環(huán)里處理生命值。核心思路是算出掩碼用掩碼決定是否寫入但這一套代碼復(fù)雜度比較高而且maskstore在不同CPU上表現(xiàn)差異大。工業(yè)方案我還是推薦swap-and-pop讓熱循環(huán)盡量簡(jiǎn)單死亡整理放到冷路徑上去做。第二輪優(yōu)化后同一臺(tái)機(jī)器上50萬(wàn)粒子的更新從8ms降到了大約1.2ms。也就是說(shuō)在原始120ms基線上整體已經(jīng)拿到約100倍的提升。下面我把整個(gè)百倍改造的完整路徑擺出來(lái)方便你直接對(duì)著自己的項(xiàng)目套。4. 工業(yè)級(jí)百倍改造完整實(shí)錄從基線到最終版本前面兩章分別講了兩輪核心技術(shù)這一章我把整個(gè)案例串起來(lái)記錄一個(gè)完整的工業(yè)級(jí)改造流程包括數(shù)據(jù)、步驟、踩坑后的調(diào)整以及最終那張關(guān)鍵的性能對(duì)比表。4.1 性能基線與瓶頸定位先別動(dòng)手先量數(shù)據(jù)接手這個(gè)工業(yè)仿真項(xiàng)目時(shí)第一步我沒(méi)有改任何代碼而是先量基線。原始代碼跑500,000個(gè)粒子每幀一次update耗時(shí)約120ms。用perf stat -e cache-misses,branch-misses,instructions,cycles ./run能看到一組非常典型的數(shù)據(jù)cache miss率超高、branch miss率接近20%、指令數(shù)雖然不多但CPI每指令周期數(shù)高得異常。這就是典型的“內(nèi)存墻”問(wèn)題。算法層面再怎么優(yōu)化也無(wú)法解決緩存行空轉(zhuǎn)和分支預(yù)測(cè)失敗的浪費(fèi)。所以定位到瓶頸后我決定按“數(shù)據(jù)布局→活躍管理→SIMD向量化”的順序推進(jìn)每一步都必須有可復(fù)現(xiàn)的計(jì)時(shí)結(jié)果。4.2 數(shù)據(jù)驅(qū)動(dòng)重構(gòu)與活躍粒子管理把對(duì)象數(shù)組拆成平行數(shù)組重構(gòu)時(shí)我沒(méi)有一次性重寫全部代碼而是先提取出一個(gè)純數(shù)據(jù)層。原來(lái)的ParticleSystem類改成一組vectorfloat成員配上alive_count記錄活粒子數(shù)量。為了兼容老接口保留了一個(gè)“根據(jù)ID訪問(wèn)組件”的輔助方法但熱循環(huán)里絕對(duì)不經(jīng)過(guò)這個(gè)接口。這一步重構(gòu)的核心收獲是代碼邏輯基本沒(méi)變但內(nèi)存訪問(wèn)模式完全變了。scalar版本更新循環(huán)里不再有if (!alive)的分支也不再有struct之間的步長(zhǎng)跳躍。第一次測(cè)試耗時(shí)就從120ms一路掉到8ms左右。順帶提一個(gè)我踩過(guò)的坑一開始我沒(méi)有做swap-and-pop只是把死亡粒子標(biāo)記后仍然留在數(shù)組里。結(jié)果雖然從AoS換到了SoA但因?yàn)閿?shù)組中間有很多死粒子cache line利用率還是不高只提升了5倍左右。后來(lái)把存活的擠到前段才真正吃到“順序遍歷”的紅利。這個(gè)細(xì)節(jié)千萬(wàn)不要省。4.3 SIMD更新內(nèi)核擴(kuò)展從計(jì)算到訪存都要對(duì)齊第二輪是在SoA基礎(chǔ)上做SIMD。我直接把更新函數(shù)改成了前面那份update_simd版本但是有幾個(gè)地方在實(shí)機(jī)調(diào)試時(shí)反復(fù)出問(wèn)題內(nèi)存對(duì)齊std::vectorfloat默認(rèn)分配只保證16字節(jié)對(duì)齊但AVX2的_mm256_load_ps要求32字節(jié)。我在初始化階段用std::aligned_alloc分配了所有數(shù)組并把分配邏輯封裝成一個(gè)AlignedBuffer類避免后續(xù)忘記對(duì)齊。數(shù)據(jù)規(guī)模50萬(wàn)恰好是8的倍數(shù)但為了通用安全還是保留了尾部的標(biāo)量循環(huán)。編譯器指令集開關(guān)編譯參數(shù)必須帶-marchnative否則即使寫了intrinsics生成的代碼也只是用SSE兼容路徑速度上不去。這一輪從8ms降到1.2ms附近。整體對(duì)標(biāo)最初基線已經(jīng)實(shí)現(xiàn)約100倍的性能飛躍。4.4 記錄性能對(duì)比表百倍是怎么算出來(lái)的完整的對(duì)比表如下。同一臺(tái)機(jī)器上數(shù)據(jù)規(guī)模20萬(wàn)和50萬(wàn)都跑過(guò)這里取50萬(wàn)的數(shù)據(jù)作為代表優(yōu)化階段每幀耗時(shí)相對(duì)基線加速關(guān)鍵動(dòng)作初始AoS分支判斷120ms1x基線切到SoA布局約35ms約3.4x字段數(shù)組化但仍有死亡粒子殘留SoAswap-and-pop活躍管理約8ms約15x熱循環(huán)無(wú)分支順序遍歷活粒子SoASIMD(AVX2)約1.2ms約100x8路并行計(jì)算除法轉(zhuǎn)乘法多線程SIMD順帶優(yōu)化約0.5ms約240x4線程并行分塊未在本文展開有人可能會(huì)問(wèn)120ms直接到1.2ms是不是我挑了一個(gè)特別適合優(yōu)化的問(wèn)題說(shuō)實(shí)話這個(gè)例子刻意選得非?!案蓛簟钡^不冷門。大量渲染粒子、物理剛體、碰撞檢測(cè)、圖像像素處理本質(zhì)上都是“同構(gòu)數(shù)據(jù)批量做同構(gòu)運(yùn)算”這類場(chǎng)景在工業(yè)級(jí)代碼里到處都是。數(shù)據(jù)量越大、瓶頸越明顯百倍收益的概率越高。當(dāng)然如果是一個(gè)邏輯跳轉(zhuǎn)特別復(fù)雜、每個(gè)元素處理方式都不一樣的循環(huán)這套組合拳效果會(huì)差很多。4.5 配套工具與編譯參數(shù)建議整個(gè)改造過(guò)程我用的工具不多但都極其關(guān)鍵Linux下用perf stat看cache-misses和branch-misses快速定位瓶頸是內(nèi)存還是分支。用編譯器資源管理器Compiler Explorer看匯編。寫intrinsics時(shí)確認(rèn)它確實(shí)生成了vaddps、vmulps這些SIMD指令而不是被編譯器悄悄降級(jí)成標(biāo)量。編譯命令建議g -O3 -marchnative -ffast-math -funroll-loops。注意-ffast-math不是免費(fèi)的它會(huì)改變浮點(diǎn)運(yùn)算的嚴(yán)格度工業(yè)項(xiàng)目里需要根據(jù)業(yè)務(wù)場(chǎng)景決定是否啟用或者只針對(duì)熱點(diǎn)翻譯單元打開。5. 常見問(wèn)題與排查技巧速查這幾條坑我替你先踩了這套方案我前后不只在一個(gè)項(xiàng)目里用過(guò)每次都會(huì)遇到幾個(gè)“看起來(lái)莫名其妙”的問(wèn)題。統(tǒng)一整理出來(lái)以后你再做能少走很多彎路。5.1 false sharing多線程下的緩存殺手當(dāng)我把優(yōu)化后的版本改成多線程并行時(shí)起初發(fā)現(xiàn)線程越多性能反而越差。原因就是false sharing——多個(gè)線程同時(shí)修改同一個(gè)緩存行里的不同數(shù)據(jù)項(xiàng)。比如兩個(gè)線程分別處理編號(hào)連續(xù)的兩段粒子可能同時(shí)寫入x[500]和x[501]而它們?cè)谕粋€(gè)32字節(jié)或64字節(jié)緩存行上CPU為了保持一致需要頻繁在核心之間同步緩存行。解決方法很簡(jiǎn)單讓每個(gè)線程處理“按緩存行對(duì)齊的塊”或者給每個(gè)線程一個(gè)本地緩沖最后再合并。最簡(jiǎn)單的粗暴做法是把分塊大小設(shè)成緩存行能容納的元素?cái)?shù)的整數(shù)倍很多時(shí)候問(wèn)題就消失了。5.2 未對(duì)齊訪問(wèn)為什么程序突然崩了AVX2版本最典型的崩潰就是未對(duì)齊的load/store。錯(cuò)誤提示往往是一個(gè)挺難看的segfault甚至直接無(wú)征兆非法指令。排查方式就是想清楚兩個(gè)問(wèn)題這個(gè)數(shù)組是用什么函數(shù)分配的它的對(duì)齊有沒(méi)有達(dá)到32字節(jié)我習(xí)慣把這類檢查寫進(jìn)調(diào)試斷言assert(reinterpret_castuintptr_t(ptr) % 32 0);不要小看這一步它能在開發(fā)階段幫你抓住90%的對(duì)齊問(wèn)題而不是等到線上崩潰。某些分配器在特定的malloc實(shí)現(xiàn)下能保證16字節(jié)對(duì)齊但保證不了32字節(jié)務(wù)必用aligned_alloc顯式指定。5.3 什么場(chǎng)景不適合這套方案數(shù)據(jù)驅(qū)動(dòng)SIMD不是萬(wàn)能鑰匙。我總結(jié)了幾類不適合的場(chǎng)景數(shù)據(jù)規(guī)模很小比如一次只處理幾十個(gè)元素。SIMD調(diào)用和內(nèi)存對(duì)齊的初始化開銷可能比計(jì)算本身還大。每個(gè)元素的處理邏輯差異極大頻繁跳轉(zhuǎn)SIMD無(wú)法打包。代碼里有復(fù)雜的虛函數(shù)調(diào)用和多態(tài)分派這些分支即使在SoA下也難以向量化。數(shù)據(jù)結(jié)構(gòu)本身必須保持對(duì)象語(yǔ)義比如依賴?yán)^承、虛函數(shù)管理生命周期強(qiáng)行改成SoA會(huì)讓代碼維護(hù)成本失控。遇到這些情況我的策略是只優(yōu)化真正的熱點(diǎn)。先用profiler量出不合理的函數(shù)再?zèng)Q定是否值得用這套方案。不要一上來(lái)就把所有代碼推倒重寫成數(shù)組結(jié)構(gòu)體。5.4 排查經(jīng)驗(yàn)速查表現(xiàn)象可能原因處理方案SIMD版本跑起來(lái)反而更慢數(shù)據(jù)規(guī)模太小或者指針別名限制優(yōu)化增大批量處理加__restrict開啟-marchnativeAVX2版本隨機(jī)崩潰數(shù)組沒(méi)有32字節(jié)對(duì)齊改用std::aligned_alloc分配加對(duì)齊斷言多線程版本性能下降false sharing按緩存行分塊或線程本地緩沖最后合并結(jié)果和標(biāo)量版對(duì)不上浮點(diǎn)運(yùn)算順序變化確認(rèn)精度容忍度必要時(shí)保留標(biāo)量路徑做交叉驗(yàn)證向量化后只提升1倍循環(huán)里有除法/開方等慢指令預(yù)計(jì)算倒數(shù)除法改乘法分支miss依然很高活躍粒子沒(méi)有集中管理用swap-and-pop把死粒子剔除出熱循環(huán)這些坑大多不是理論問(wèn)題而是實(shí)機(jī)調(diào)試中換了無(wú)數(shù)方案才摸索出來(lái)的。你照著速查表走一圈大概率能省下兩三天排查時(shí)間。最后說(shuō)點(diǎn)我個(gè)人的體會(huì)。優(yōu)化這類系統(tǒng)時(shí)我最大的感受是別跟你的算法較勁先去跟你的數(shù)據(jù)布局較勁。同一個(gè)數(shù)學(xué)公式放在錯(cuò)的布局里可能跑120ms放在對(duì)的布局里配合SIMD可能只要1ms。數(shù)據(jù)驅(qū)動(dòng)不是說(shuō)面向?qū)ο蟛缓枚翘嵝阉泄こ處煷a是寫給CPU和內(nèi)存體系跑的你沒(méi)把數(shù)據(jù)喂到它嘴邊它再?gòu)?qiáng)也白搭。另外一個(gè)經(jīng)驗(yàn)是永遠(yuǎn)讓基準(zhǔn)測(cè)試說(shuō)話。我見過(guò)太多人憑“感覺(jué)”優(yōu)化最后改了一堆代碼性能沒(méi)有任何變化甚至更差。每一步優(yōu)化都記下時(shí)間、記錄cache miss和branch miss數(shù)據(jù)你才能真正知道是哪一步發(fā)生了質(zhì)變哪一步白忙活了。這套方法后面還可以繼續(xù)擴(kuò)展。比如配合多線程分塊處理、使用AVX-512指令集、用std::span做視圖層、或者把相同思路推廣到碰撞檢測(cè)和渲染系統(tǒng)。但核心始終是那句話先讓數(shù)據(jù)緊湊地待在緩存里再讓CPU一條指令多干幾件事。你手里的那些熱點(diǎn)循環(huán)大概率也能拿到同樣驚人的收益。
返回列表
PREV
查看更多資訊
NEXT
返回資訊列表
亚热日本熟女| 日韩少妇无吗| 国产一级高跟丝袜| 综合性视频99| 在线精品福利免费播放| 亚洲欧洲日韩中文字幕一区| 婷婷九月| 99久久久久久亚洲精品不卡| 国产精品极品美女视频| 91亚洲狠狠色| 天美传媒国产原创中文字幕亚洲欧美另类 | 国产伦乱91| 欧美日韩不卡传媒| 久久精品无码不卡| 国产天天看| 岛国色情视频在线观看| 欧美激情亚洲| 欧美精品久久96人妻无码| 性饥渴少妇av无码毛片| 九热超碰| 9久精品视频在线观看| 日韩A优精品在线观看| 欧美黑人日韩少妇色情| 人妻少妇精品久久久| 尤物av网站| 欧美人妻久久精品二区三区| 中文字幕精品探花视频| 久久久国产av美女私房| 中文字幕一区二区视频在线观看 | 少妇大屁屁| 91精品久久久久久久久久| 亚洲精品成人| 少妇啪啪自拍| 思思热一热婷婷热一热| 久久久国产精品人妻丝袜| 天天看综合网| 国产99久久99热这里只有精品15| 少妇高潮九九九九| 99re综合伊人| 夜夜嗨一区二区三区直播内容| 国产久久久9999| 色青青久久影视| 色狠狠 - 百度| 1024人妻熟女一区二区三区| 日韩一级成人毛片免费观看| 在线观看av区| 另类在线| 伊人成人中文字幕久久网| 91丨九色丨国产丨人妻在线 | se吧提供国产乱老熟视频胖女人| 久久无码成人| 丝袜 亚洲 偷拍| 激激五月| 欧美色图人妻| 试看60秒| 热99这里有精品综合久久| 日日摸日日碰夜夜爽视频| 国产精品不卡一区二区三区| 麻豆天美一区二区| 99热99在线播放激情| 无码国产精品久久久久| 欧美极品少妇交| 蜜伊人色综合97| 激情五月激情综合网| 91c色| 欧美东京热精品A∨| 天天视频综合在线观看视频| 免费视频无码| av东京热男人的天堂| 九九九九九九九| 91无码人妻精品一区二区三区蜜桃| 97美日韩视频| 97超碰磁| 免费1级a做爰片观看| 男插女青青影院| 久久久久少妇| 97超碰人人操人人操| 91少妇| 日韩三级天堂在线观看| 久久久精品国产亚洲伊人| 日韩啪啪啪视频| 怡春苑东京热| 97少妇人妻中文字幕久久 | 亚洲高清无毛一区二区| 九九在线视频| 99re在线视频国产| 国产狂喷潮在线精品| 妺妺跟我一起洗澡没忍住| 国产精品无码论坛| 蜜臀在线免费观看在线免费观看| 欧美同性恋 的搜索结果 - 91n| 久久久久九九九九| 青青草吊丝| 亚洲资源一区| 美女操逼福利视频| 亚洲色图国产另类| 91美女视频| 免费看久久久性性| 久久久久国产精品人妻aⅴ天堂| 国产女大学生AV| 日本中文字幕在线视频| 伊人综合色网| 伊香蕉综合久久久久久久噜噜噜| 久久草在线综合视频| 亚洲视频小说| 眼镜人妻101.com| 欧美色图亚州激情| 免费少妇一区二区| 97色视频在线| 亚洲h片在线免费观看| 久久熟女人| 久久99草| 国产美女裸体秘 永久无遮挡| 高潮内射在线| 青青草久草| 久久婷婷六月综合| 天天色怡春院| 中文字幕一区电影在线观看| 欧美性爱第一页久久| 大地资源在线观看中文第二页| 久操在97| 老熟女乱伦一区| 麻豆60秒| 天天综合欧美黑人| 特级毛片特黄久久免费看| 好看的91视频| 久久精品国产Aⅴ| 老色69| 亚洲精品国语在线播放| 丁香五月婷婷基地| 91麻豆天美| 亚洲精品久| 精品99999| 婷婷久草一区二区三区| 亚洲中文字幕精品一区| 久久久久ab| 人妻人人做人人澡人人爽欧美一区| 91丝袜美腿片| 午夜啪啪片| 亚洲日本男人天堂网| 丰满熟女人妻一区二区三五十一路| av网站免费看| 91黑丝操| 九九探花视频在线观看| 少妇精品久久久八区九区| 草莓精品视频| 国产无码成人无码| julia ann久久| 操逼操操操91| 黑人免费福利视频| 亚洲人精品午夜不卡| 日本一级黄色电影| 边做饭边操逼逼| 男人的亚洲天堂| 国产67194| 亚洲中文字幕一区二区| 色婷婷婷五月天激情四射| 日韩精品一区二区日韩| 熟妇人妻精品一区二区| 69精品人人人人| 亚洲人妻中文高清| 看日韩黄片| 欧美青青草视频| 欧美亚洲国内自拍| 超碰人人色| 中文字幕日韩专区精品系列| 人人妻碰人人免费| 992视频一区| 欧美熟女妇同| 91N五十路| 男女激情黄色网址| 国产成久久综合片| 亚洲毛片久久| 日韩精品午夜操呦呦不卡影院| 99re在线观看| 伊人色综合网| 九九黄色视频在线观看| 老司机老司机午夜影院| 国产精品美女久久久久久网站| 香蕉免费一区二区三区不读| 欧美大香蕉卡久久| 99热免费| 一本道综合色图| 日本在线不卡v二区| 日本孕妇孕交| 久操| 九草九九九| 欧州激情视频在线一区二区| 绑缚麻绳人妻寝取完整版| 资源在线观一 二| 日韩欧美午夜一区二区| 欧成人精品H无码| 久久超碰av在线| 淫骚熟女一区二区三区| 骚逼一区二区| 久久宗合亚洲| 大粗鳼巴久久久久| 一区二区三区一亚洲中文字幕、综合区灬 | 后入式视频国产自| 精品一区二区三区四区外站| 日韩精品熟妇| 夜夜久久| 国产成人主播| 亚洲大色鬼| 97网址97| 久久久精品网| 久久久久久中文| 色悠久久久av| 91热| 国产偷拍网站| 伊人网免费视频| a亚洲欧美色欲| 免费福利视频中文字幕| AV一区观看| 国产久久成人| 日韩精品视频在线观看一卡二卡| 欧美日韩国内不卡| 不卡在线一区,精品一区二区三区中| 久久久专区| 久久深夜无码| 中国91AV| 欧美午夜视频免费观看| 久久精品店| 欧美 亚洲 偷拍自拍| 男人的天堂亚洲| 中文字幕在线观看网页| 伊人伊人LD| 91国产丝袜美女| 亚洲色婷婷综合久久一区二区三区| 亚洲天堂另类| 欧美成熟性爱精品| 亚洲午夜福利在线影院| 天天日夜夜| 欧美乱色| 欧美偷| 97资源久久| 成人av毛片在线观看| 亚洲字幕一区二区| 99久久婷婷国产综合精品草原| 日韩一级二级| 日本熟妇精品九九| 免费成人自拍视频在线| 97任你吞精| 能看的av| 美女91av| V A在线| 亚洲操逼视频网站| 日本丝袜美腿人妻九九| 99精品无码| 国产精品人妻无码久久久互動交流| 青春草莓视频在线观看网址| 秋霞无码av鲁丝片一区| 麻豆国产原创AV色哟哟 | 影音先锋中文字幕日本好一区二区| 婷婷色色网| 亚洲色图 综合| 超碰色97| 亚洲Av无码成人精品国产| 欧美人妻精品| 色综91| 成人免费福利在线观看| 天堂资源欧美| 综合久久99| 欧美成人一级免费电影| a人欧美综合天堂麻豆| 蜜桃久久一区二区| 黄片不用下载在线观看| 人妻少妇三级| 边做饭边操逼逼| 精品国产精品一区二区| 婷婷8月天青娱乐| 神马久久久久久伦理片| 91欧美美女日韩国产婷婷| 熟妇激情| 97碰在线视频| 99精品视频在线观看免费| 亚洲色图久久精品蜜| 97人人色| 日本午夜精品理论片A级APP发布| 在线亚洲丝袜视频网站| 17c在线成人免费A片观看| 麻豆天美国美国产AV| 日日骚av| 亚洲国产综合图区中文字幕| 岛国在线一区二区三区| 色九九九综合| 日本三级一区二区 在线| 99r九九| 久久久性爱| 99久久久久| 大香蕉99re| 国产麻豆一级精品视频| 一本色道久久综合狠狠操| www.大香| 大屁股熟女一区二区三区| 园内精品自拍视频在线播放| 欧美乱妇狂野欧美在线视频| 91成人精品在线播放| 天天草AV| 色婷婷电影网| 男女猛烈无遮掩视频免费软件| 91老熟女逼| 超碰97人人cao| 在线97在线| 久久国产乱子伦精品免费女人| 操一区| 国产女人与拘做受视频免费| 97超碰中文| 国产做?爰片久久毛片?片美国| 成人开心网在线视频| 国产亚州日韩欧美看片| 超碰在线人人射| 99热在线不卡| 免费的黄片wwwwww| 91人妻人人澡人人爽人人精品| 91足交| 青青草久久| 综合一区中亚洲国产成人综合精品 | 亚州熟妇精品| 国产成人无码网站在线视频| 少妇高潮九九九九| 国模不卡一本二本三电影| 乱伦av麻豆| 98超碰欧美| 天天舔九色婷婷| 午夜福利视频在线一区| 精品人妻视频入口| 超碰97人人乐| 影音综合网| 国产 v乱码一区二| 精品无码一区二区三区| 天天碰久久入| 老司机久久| 九九热在线精品视频| 欧美人人操人人插| 中国91AV| 中文字幕色AV| 国产成人精品午夜福利| 99热免费| 五月丁香久久| 精品黑人一区二区| 免费αⅴ在线观看| 欧美91精品国产自产| 97在线资源| 欧美另类色图片| 97香焦色区| 欧美成人AⅤ大片在线观看| 久久精品久| 国产97在线播放| 久久九七| 久久这里都是精品| 色噜噜狠狠色综无码久久合欧美| 欧美一区二区观看在线| 六月丁香啪啪| 国产精品熟女乱伦| 97国产高清视频在线观看| 日本不卡五区| 中文字幕在线观看网页| baisiav| 久草大| 日va操| 综合国产影视三级| 18禁看网站一区| 91岛国动作片| 午夜噜噜噜| 国产又大又粗又长视频| 欧美91久久久久| 91色伦综合| 亚洲精品天天影视综合网 | 天天躁日日躁狠狠躁| 91四海无码日韩欧美| 欧美亚洲涩涩| 97超碰超欧美。| 中文字日本乱码| 日本性爱少妇| 五月天婷精品激情| 亚洲AV无码国产精品久久久久| 熟妇的味道HD中文字幕| 密乳无码| 亚洲一区二区三区欧美日韩| 天堂中文资源在线bt| 久久毛卡| 丁香五月激情综合国产| 香蕉综合网| 九九热在线精品视频| 久久久中文| 激情五月婷婷综合| 97超碰无码网| 国产精品久久久久久久久久久久久久久久久久| 中文字幕视频免费| 久欲AV| 亚洲日韩资源| 色妇综合网| 精品午夜福利| 性爱视频免费网址| 亚洲一欧洲中文字幕在线 | 99re9这里只有精品| 亚洲综合99999| 先锋音影AV| 老色鬼成人精品视频下载大在线观看| 91白虎| 精品视频一区二区| 精品久久久久久中文字幕三区| 乱伦av国产| 午夜免费福利视频一区| 狠狠躁AV| 天天插天天操天天摸天天射天天看| 蜜桃臀久久| 丁香九月婷婷| 日逼视频日本| 天美精品av| 欲射影视| 97在线视频网站| 欧美综合国产精品久久丁香| 大香蕉免费乱伦视频| 日韩欧美视频青青| 91处女视频在线观看| 啊啊啊啊,啊啊好多水| 99久久99久久免费精品蜜臀| 黄色av网站在线播放| 色婷婷综合视频| 欧色综合| 高潮精品| 日本肏逼视频在线观看| 夜夜操av亚洲一区二区| 国产国产亚洲一二三久久| 欧美国产精品久久九九| 久久露脸国产老熟女| 97综合在线观看| 97超碰中文字幕| 欧美巨大性舒爽顶到了| 九色视频91| 91久久18禁| sewuyueav| 国产成人午夜视频网址| 亚洲熟妇图片| 欧美色就是色| 五月婷视频| 九九热精彩视频| 国产精品日日摸夜夜添骚逼| 综合欧美日本三级| 九九九九九用不成了| 加勒比综合网| 长长久久88视频| 少妇熟女视频一区二区三区| 三级AV入口| 少妇毛片久久| 青青在线视频日韩欧美| 五月激情在线| 一区二区视频在看| www.婷婷| 日韩猛交| 欧美图片偷拍| 69精品| 激情开心五月天| 久久久一二三四区| 亚洲色图殴美色图激情乱伦| 欧美高潮| 综合色99| 91AV国产精品| 亚洲精品三| 鸡巴插逼视频| 青青草国产盗摄一二三区| 久久国产AⅤ| 五月天伊人| 日本性交操一区二区不卡系列| 69超碰综合| 欧美色图电影| 欧美亚洲激情小说| 日韩一级久久毛片| 久久嫩草国产成人一区| 国产乱伦亚洲| 午夜AV污污污| 亚洲乱熟女一区二区三区大香蕉| 亚洲骚逼少妇| 天堂九九九九九九九九九| 97天堂| 国产精品小视频一区二区三区| 91情色| 免费9 1久久| 欧美日韩国产黄色片| 九一性生活免费视频| 免费在线观看国内色片网站网址| 久久大香蕉97| 91九久| 青娱乐欧美激情一区二区| 91爱做| 国产精品久久久久久久久AV大片| 啊啊啊水好多| 91久久午夜无码鲁丝片久久人妻| 18禁网站在线播放| 日本加勒比无码专区| 射丝袜高跟鞋99| 高潮毛片无遮挡高清免费| 日韩不卡一二三四| 色婷婷综合久久久久中文国产精品一区中文字幕,国产福利电影一区二区三区 | 欧美色综合| 亚洲自拍一区夜夜操| 日韩国产乱子伦App| 加勒比海人人操超碰在线| 亚洲熟女乱色| 国产精品久久久久久片| 亚洲中文字幕在现观看| 成人精品视频| 国产精品乱人伊人网| 亚洲一区二区久久久久| 色爱亚洲| 国产精品九九| 婷婷综合在线观看| 人妻-91porn| 国产精品高潮久久久无码| 欧美在线 亚洲| av天天在线观看| 国产黄色 A 片免费看| 久久久久久九九九九| 神马久久69| 天天综合网国产| 午夜福利视频在线一区| 五月天我淫我色av| 亚洲熟妇A V黑人| 我中文字幕6区| 国产丝袜美女诱惑| 国产福利第一视频| 综合操逼| 天天操天天射天天日| 国产一区二区在线播放| 人妻人久久精品中文字幕| 久久久久9999妇女| 天天看天天综合成人网| 五月天婷婷基地| 性在久久久久久| 综合亚洲欧美精品日韩?v| 午夜操一视频一区| 人妻素股| 丰满人妻一区二区中文| 91高跟美女在线播放| 91oumei| 免费A V在线| www.久久最新地址| 欧美日韩大黄片| 日韩激情无码影院| 国产午夜精品在线观看| 97精品一区二区三区免费| 哑洲在线| julia ann久久| 东京热不卡视频| 好好的日:com久久九九| 中文字幕片| 99久久无色码| 刺激性视频黄页| 久久久999网站| 97爱免费插| 国产精品一区二区三区在线密挑| 婷婷久久五月天| 大香蕉人妻| 婷婷久草| 日韩精品一二三四| 久久久久中出| 亚洲精品欧洲精品| 人妻熟女一区二区三区在线| 中文字幕十五区| 久久视网78| 欧美久久婷婷| 蜜桃视频啊啊啊啊| 四虎免费在线播放| 亚洲国产97在线精品一区| 舔人妻中文免费视频| 欧美色亚洲色| 亚洲在饯| 欧美日韩午夜精品一区二区三区| 1769一区| 奇米狠999| 91粉嫩萝控精品福利网站_精品影音先锋国 | 亚州操操穴网| 国产肏屁眼视频| 美熟女逼导航AV操逼| 亚洲另类色综合网站| 唯美清纯 妖精视频| 亚洲男人天堂网| 人妻中文字幕精品无码| 久久久精品成人国产| 黄污污污污| 操操操操操操| 青青操日韩| 国产精品com| 激情无码日韩| 91色综| 日本精品性生活久久久| 96一区二区三区| 亚洲不卡三级手机播放| 久久国产热视频97电影| 色九区| 色婷婷婷五月天激情四射| 蜜臀aV午夜一区二区三区| 日韩人妻丝袜中文字幕| 大黄片做爱的大的| 中文字幕第页| 96久久久精品| 亚洲欧美另类激情小说| 成人性爱美曰韩| 熟女人妻久久中文字幕一二区| 91av天美性媒精品视频| 深喉吞精| 404操逼福利视频| 色一射色一射| 2017天天操天天日| 亚洲成人日韩小说| 澳门人妻久久| 快灬快灬 一下爽蜜桃在线观看 | 粉嫩少妇自慰在线| 大香蕉78| 九九色精品| 97精品在线| 免费在线看黄片av| 丁香五月激情啪啪| 欧美黑人91| 国产美女自拍AV| 粉嫩国产精品久久粉嫩| 999九九九九国产动| 无码人妻精品一区二区三区99不卡| 婷婷综合五月| 激情四射婷婷六月天| 麻豆国产精品午夜视频| 国产乱码久久| 青娱乐黄色录像| 性做久久久久久免费观看软件| 久久神马影院| 免费无码婬片AAAA片直播色戒| 蜜桃狠狠色伊人亚洲综合 | 少妇天堂| AV综合中文字幕干| 99re在线视频这里只有精品| 人妻人人做人人澡人人爽欧美一区| 女人一区| 日小BB小视频| 日韩精品99久久久久久中文字幕| 日本性感人妻91| 性色avv| 成人国产视频在线观看| 亚洲天堂人妻一区二区| 亚洲乱妇p22| 狠狠 91| 99色网| 久久大香蕉手机高清视频| 狠日欧美| 强奸少妇AV导航网| 中国操逼无码| 91丝袜激情在线| 日韩无码精品综合久久| 97超碰在线资源网站| 在线a v| 60秒免费视频| 欧美一区二区亚洲天堂| 猛猛干| 91久精品| 欧美探花网| 青青草狠狠撸| 啊视频在线| 欧洲精品一级二级精品综合视频综合| 亚洲日本韩国极品一区二区| 一区AV| 日日嗨AV一区二区夜夜| 精品亚洲国产成人AV制服丝袜| 欧美综合综合| 国产13区| 免费在线黄片视频| 怡红院久久老司机| 91暧暧| 日韩亚洲中文字幕在线| 黑人性欧美| 超碰 另类 欧美| 性在久久久久久| 国产精品久久久亚洲第一牛牛_在线观看| 久久一二三四五六七八九区区区| 亚洲美女AV无码| 亚洲少妇色图自慰直播| 日韩去日本高清在| 黑人娇小av在线播放| 人人澡人人弄| 久久草草欧美精品| 亚洲欧美日韩二区视频| 国产又粗又长视频| 丝袜无码a片| 337p大胆噜噜噜噜噜91Av| 久久永久无码人妻视频| 青青草中日韩在线| 亚洲s在线观看| 日韩av在线免费网站| 精品人妻一区二区三区日产| 91美女看B| 久久精品一区二区三区不卡| 日韩色欲久久一二三四区| 91精品人妻一品二品三品| 97天天做| 日本91白丝| 九月丁香综合网| 国产在线视频午夜精华在| 九九免费影片| 啊啊啊不要啊啊受不了了视频在线 | 亚洲最新中文字幕免费| 91美女网站| 日本熟妇自慰性高潮一区二区三区| 97人妻色| 熟女视频久久| 亚洲AV噜噜狠狠网址蜜桃动漫| 丰满人妻一区二区三区| 亚洲久草AV色图| 亚洲色香| 99999精品成人| 五月婷婷六月激情| 天天色综亚洲91污| 午夜亚洲国产理论秋霞| 中文一区二区三区影院| 超碰97男女| 东京热AV男人的天堂| 怡红院成人av| 熟妇熟女一区二三区| 资源在线观一 二| 91性高潮久久久久久久久| 女同女同恋久久级三级| 亚洲无码精品AV久久久| 国产一二三在线视频五十路| 午夜噜噜噜| 91激情国产| 大香蕉伊然在亚洲91| 欧美日本天堂| 啊啊啊啊在线观看网址| 天天亚洲综合| 97中文字幕色| 国产精品。| 九九成人精品| 国产精品色哟哟| 秋霞男人网| 国产美脚女优尤物在线观看| 嗯嗯,啊啊,国产精品| 久久人人妻| 精品人人| 人妻无码后入| 久草资源欧美在线视频| 亚洲美女30b| 成人五月天色网| 久偷拍欧美日韩三区| 97AV在线免费观看| 日本新免费二区三区| 男人的天堂日本东京热| 曰韩少妇无码| 日本久久久久久久久久| 国语精品av| 中文字幕在线免费观看 | 亚洲**2021在线观看| 亚洲日韩精品久久久久一区壹牛 | 国产天天骚| 中文久久一区| 欧美91网站| 91精品少妇搡搡搡| 亚洲精品黄码久久久久| 亚洲天天更新| 视频国产成人精品日本亚洲18| 久久精品人人做人人看| 波多野42部无码喷潮在线观看 | 亚洲av综合色区无码一| 强奸乱伦AV一天堂网| 久久一区二区高清免费| 中文字幕免费在线观看| 国产AV超爽| 黄色操人| 粉嫩av在线| 2017大香蕉国产精品久久| 嫖老熟女A片一二三区| 妇女性内射冈站HDWWWCOM| 日韩中文字幕国产| 日本熟妇一区二区三区| 78精品| 亚洲成人在线播放| 97在线视频免费看| 日本三级大片| 美女91AV| 91美女视屏| 私人尤物在线精品不卡| 91精品国产综合久久久蜜臀| 欧美色女人| 偷窥自拍亚洲色图| 九九九精品成人免费视频小说| 中文字幕日韩国产传媒欧美精品| 欧洲精品一级二级精品综合视频综合| 五月色综合| 热99re69精品8在线播放| 红杏大香蕉| 麻豆三极片| 熟妇视频一区二区三区在线观看| 亚洲成人精品在线一区| 神马午夜久久久| 国产精品美女在线一区| 九九人妻| 色婷婷狠狠| 日本一道在线播放高清| 久插综合| 老司机射| 超碰美国| 欧美狠狠弄| 亚洲成人av电影在线| 亚洲影视高清第一页| 丁香六月激情综合| 麻豆三极片| 国产精品亚洲日韩骚欢乐谷最新地址发布页huanieguty性屋娱乐妖精视频 | 91 国产丝袜在线放观看| 国产日韩无码一区二区三区久久区| 亚洲色香| 99综合免费视频| 日韩一级久久毛片| 91熟女.com| 精品国产一区二区三区av在线资源| 97天堂| 天天超级碰碰碰| 久久99久久99精品免视看婷婷| 国产精品久久久| 二三四区精品| 日本久久网| 777琪琪午夜免费A片| 欧美肥臀在线| 老熟女区| 亚洲天堂热| 欧美A片中文字幕| 抽插一区二区视频| 97色色色综合网站| 激情综合婷婷| 男人的天堂午夜av| 大香蕉中文201| 国产人妻一区二区三区欧美毛片| 免费黄色片子| 少妇啪啪自拍| 91精品国产一区三一| 国产亚洲精品美女| 夜夜中出国产| 色欲日韩欧美在线一区| 国产 日韩,欧美 自拍| 色五月AV在线| 亚洲精品骚逼| 久久人妻丝袜一区二区三| 国产成人欧美一区二区三区的国产| 亚洲色图A| 后入福利视频| 久久綜合很很很| 少妇超碰在线| 久久久久久久国产a∨| 欧美日韩国产成人高清| 亚洲第二页| 亚州高清色综合| 精品无码一区二区| 欧洲熟妇xxXx欧美老妇裸体| 精品毛片av一区二区| 久久九色| 色图四区| 一本一道久久综合久久| 久久女同性恋一二区| 男人的天堂成人的社区| 日韩精品国产精品五码一区二区| 热99这里只有精品| 久久成人午夜精品影院| a片 xxxx受爽视频| 丰满人妻-区二区三区| 日韩青久久| 欧美在线中M| 蜜臀久久久| 日韩久久超碰色| 国产精品天美传媒| 猛交交| 日本一本一区二区三区四区五区欧美日韩中文字幕 | 亚洲情色综合网| 久久同城AV| 一直超碰| 国产白领连续中出在线播放| 情色av电影| 啊啊啊啊啊操我视频| 久久久一热在线播放| 久久久久13| 精品国产乱码久久久久久久久1| 激情丁香婷婷| 色吧五月| 色欲天天综合网| 丁香六月啪| 超碰在线91| 天天日日夜夜| 偷拍伦理视频| 97舔舔| 熟妇女人妻呻吟久久AV| 欧美三级一级| AV老汉| 伊蕉97蜜桃97狠狠综合干| 搞中出视频在线观看| 色娱乐色呦呦夜夜夜夜av| 日韩av色图| 欧美日韩中国x| 舔人妻中文免费视频| 亚洲猛交| 在线97视频| 国产兽交视频在线播放| 国产日韩精品人妻久久久久色欲网站| 国产精品国产自产高清AV| 精品毛片av一区二区| 99re公开精品免费视频 | WWW.操逼.COM| 另类小说综合网| 操高情无码| 欧洲熟妇xxXx欧美老妇裸体| 色婷五月天| 人人污日韩一区二区| 亚州 综合 色图| 天天天堂影视日韩亚洲91| 人妻少妇无码| 久久9久| 成人小说视频在线精品欧美| 久久av成人无码免费| 色色婷婷五月天| 老鸭窝亚洲毛片| 天天看特黄的免费网站 | 性色高清在线| 色偷综合| 啊啊啊啊啊啊在线| 极品欧美一区二区三区| 乱欲一区二区| 夜夜一区二区| 玖玖爱一区在线| 无码二级三级| 天天射天天操天天干天天吃2018| 日本无码1| 丁香五月成人| 加勒比日本在线| 性感美女91影视| 精品无码一区二区三区| 99日精品欧美国产| 欧美熟妇乱码在线一区| 天天日熟妇| 欧洲性爱无码区| 天天做日日做天天欢。| 天天射网| 亚洲校园激情| 高清国产无码av| 97人人干人人操| 亚洲色性情三级| 97视频播放| 超碰无码加勒比| 亚洲天堂区| 99999这里都精品| 久久精品人妻一区| 立川理惠无码一区二区| 狠狠97| 亚洲天堂在线怕怕视频| 丁香五月影院| 欧美激情久久久久| 91丝袜在线观看| 日本三级日本三级99| m欧洲一级午老| 啊啊啊好想要| 色色婷婷丁香| 欧美激情久久久久| 国产1024在线播放| 激情综合色| 91日日夜夜| 亚瑟国产精品久久无码| 91欧美高清| 97鸡把在线视频| 欧美成人一级免费电影| 国产天天看| 天天看天天日| 九九热精品| 女人18精品一区二区三区| 亚瑟国产精品久久无码| 夜夜操老骚逼视频网站| 日韩欧美传媒一区国产| 最新日韩黄片| 超碰无码五月97| 国产AV色黄看到爽| 桃色六月天| 亚洲啪啪综合?v一区综合精品区| 九九Av| 综合亚洲网| 91狼人| 日韩毛片9| 在线无码操| 日韩综合97P| 国内毛片婷婷六月色| 欧洲亚洲人妻无码中字久久三区四区| 成·人免费午夜在线观看| 99色综合| 天久久久噜噜噜久久国产精品爽爽| 97香蕉碰碰人妻国产欧美| 国产天天噜一噜久久久| 久久免费精品视频免一| Julia Annxxxxx| 日韩Va亚洲va欧美Ⅴa久久| 九九自拍伦理| 国产日韩欧美亚洲精品95| 亚热日本熟女| 中日韩熟女| 欧美综合传媒| 黄片不用下载在线观看| 欧美色道啊| 精品成人av一区二区三区在线| 国产欧美日产一区二区三区 - 国产欧美日| 国产av又色又爽又黄| 91九九九吃| 国产视频一区二区免费| 亚91网| 91N欧美| 日韩成人性日韩成人性爱视频在线免费观看 | 摸奶性爱视频网站在线免费播放| 亚洲色图欧美色图制服丝袜| 伦激情人妻另类人妻| 天堂伊人久久| 色婷婷九月天天综合| 桑老女人九区| av天堂影视中文在字幕在线中文| 七月丁香婷婷| 日日A∨| 欧美性爱十八禁| 日本在线999| 大香蕉AV丝袜| 午夜超爽| 亚洲精品97p| 操九九九九九九| 亚洲色系另类精品国产| 欧美激情亚洲情色| 色婷婷丁香五月天| 国产高清午夜成人在线观看| 久久一二三四五六七八九区区| 人人操人人uiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii | 精品久久久一本一道| 色性综合| ..日韩av毛片精品久久久| 亚洲春色欧美| 中文字幕少妇色| 自拍偷拍 日韩无码| 国产精品久久久久婷婷二区次| 欧美最婬乱婬爆婬性视频 | 国产精品无码av嫩草| 欧成人在线| 少妇一区二区三区在线观看| 性色av网站| 欧美性天天| 97热视频在线观看| 天天日老熟妇| 性开放中文AV高清无码免费看| 综合色区偷拍| 怡红院成人av| 91粉芽高清在线一区二区| 懂色中文一区二区三区 | 91美女看B| 乱精品一区字幕二区| 中文字幕中文字幕一区二区| 日本加勒比无码专区| 走光一区92下载| 青草青青久久久久久国产| 国产精品制服丝袜清纯唯美 | 夜夜爽夜夜摸夜夜操免费视频| 国产亚洲 中文欧美久久| 无码聚合| 日日操免费视频| 中文区中文字幕免费看| 97超碰亚洲| 综合色图亚洲欧美| 特级丰满少妇一级AAAA爱毛片| 日本一级真人黄色性爱视频| 骚货 中文字幕 av| 成人天天看站长推荐| julia高潮后不停追击中出| 强奸乱伦大香蕉| 91在线视频国产网站| 久久久青草青青国产亚洲免观精品高清完整版_97久久综合区小说区图片区,国精品 | 青娱乐淫乱1314| 少妇精品| 亚洲怡春院| 神马久久啊啊| 中文字幕少妇色 | 欧美婷婷五月天| 欧美激情另类一区二区| 国产又黄又爽| 伦理第一页| 欧洲一区二区| 日韩高清一二三| 国产小炒后入式| 国产农村妇女精品1区二区| 婷婷中文字幕| 国产一区二区三区影片| 97人人操人人摸人人爱| 黄色人人| 日本羞羞的视频在线播放| 一区二区三| 久久久日本电影| 色97欧美| 久肏视频字幕| 91精品国| 日韩无码服务区| 人澡逼| 91美女视频电影| 久久人妻少妇| 91艹| 男人的天堂日韩| 久操视频免费观看| 乱子伦一区二区三区国产精品| 久久综合女优| 97精品久久久久久久| 九九成人精品| 人人超碰在线观看黄| 麻豆婷婷成人一二三| 色狠狠综合噜一二三区| 亚洲av总站| 夜夜嗨av午夜成人| 五十路熟女工口 | 亚洲日本韩国极品一区二区| 69人妻精品一区二区绯色| 五月婷婷综合在线| 超91综合网| 中文字幕日韩国产传媒欧美精品| 色综合美国| 久久色一区| 亚洲日韩青青草色月| 91美女在线看| 2017超碰| 老鸭窝在线视频播放| 午夜亚洲| 伊人久久AV诱惑悠悠| 日本操逼无码| 人人贴人人摸| 看黄片视频免费| 无遮挡h肉动漫在线观看| 丁香六月婷婷| 美女露胸露奶头| 国产中文福利| 哑洲在线| 午夜精品久久99蜜桃的功能章节| 91亚洲色图| 色色网91| www.色操逼| 婷婷日韩一区二区三区中文字幕在线| 97蜜桃综合| 亚洲性猛| 久久精品操| 99久久精品国产系列| 狠狠中文字幕| AAA久久| 桃色六月天| 亚洲一二三四区在线免费看视频| 中文字幕视频二区| 天天看精品动漫视频一区| 激情国产乱伦Av| 婷婷五月色| 97色97好| 神马久久久久久久久| 午夜性生活av免费在线看| 国产精品黄色三级av| 99热思思| 久久中日麻豆| 久久精品操| 精品无码一区二区三区| 色爱三区| 人人摸人人干| 亚洲资源吧| 国产中文字幕在线点播| 99视频在线|