Hacker News

Яагаад эхний C++ (m) хуваарилалт үргэлж 72 KB байдаг вэ?

Сэтгэгдэл

1 min read Via joelsiks.com

Mewayz Team

Editorial Team

Hacker News

Таны анхны C++-ийн хуваарилалтын цаад нууц

Та энгийн C++ програм бичдэг. Ганц шинэ int. Дөрвөн байт. Та strace эсвэл өөрийн дуртай санах ойн профайлыг асаана, тэгээд л таны процесс үйлдлийн системээс ойролцоогоор 72 КБ-ыг хүссэн. 4 байт биш. 64 байт биш. Бүтэн 72 КБ. Хэрэв та хэзээ нэгэн цагт энэ дугаар руу ширтэж, таны багаж хэрэгсэл танд худал хэлж байна уу гэж бодож байсан бол та ганцаараа биш юм. Хачирхалтай мэт санагдах энэ зан байдал нь C++ хөгжүүлэгчид анх удаа санах ойн дотоод мэдээллийг судалж байгаа хамгийн түгээмэл асуултуудын нэг бөгөөд хариулт нь биднийг таны код болон бодит техник хангамжийн хооронд байрлах давхаргуудаар дамжуулан гайхалтай аялалд хүргэдэг.

Та шинэ

гэж залгахад юу болох вэ

72 КБ-ын тоог ойлгохын тулд та хуваарилалтын гинжийг бүрэн хянах хэрэгтэй. Таны C++ код new int-ийг ажиллуулах үед хөрвүүлэгч үүнийг оператор new руу шилжүүлэх бөгөөд ихэнх Линукс системүүд дээр glibc-ээс malloc руу шилжүүлдэг. Гэхдээ malloc нь цөмөөс 4 байт санах ойг шууд шаарддаггүй. Цөм нь х86_64 дээр ихэвчлэн 4 КБ хэмжээтэй хуудсуудаар ажилладаг бөгөөд системийн дуудлагын зардал нь энгийн санах ойн хандалттай харьцуулахад асар их байдаг. Хуваарилалт болгонд brk() эсвэл mmap() гэж дуудах нь ямар ч ач холбогдолгүй програмыг зогсооход хүргэдэг.

Харин оронд нь glibc-ийн санах ой хуваарилагч — ptmalloc2 гэж нэрлэгддэг хэрэгжүүлэлт нь өөрөө Даг Лигийн сонгодог dlmalloc-ээс гаралтай бөгөөд зуучлагчийн үүрэг гүйцэтгэдэг. Энэ нь цөмөөс том санах ойн блокуудыг авахыг хүсч, дараа нь таны програмд ​​шаардлагатай бол тэдгээрийг жижиг хэсгүүдэд хуваана. Энэ нь таны эхний 4 байт хуваарилалт нь үйлдлийн системд илүү том хүсэлт гаргах үндсэн шалтгаан юм. Хуваарилагч нь үрэлгэн биш байна. Энэ нь стратегийн ач холбогдолтой юм.

72 KB-г задлах: Байтууд хаашаа явж байна

Анхны хуваарилалтын нэмэлт зардал нь нэг байт санах ойг танд өгөхөөс өмнө ажиллах хугацаа нь эхлүүлэх ёстой хэд хэдэн ялгаатай бүрэлдэхүүн хэсгүүдээс бүрддэг. Бүрэлдэхүүн хэсэг бүрийг ойлгох нь тухайн тоо яагаад хаана буудгийг тайлбарладаг.

Нэгдүгээрт, glibc-ийн malloc нь үндсэн талбарыг эхлүүлдэг — үндсэн хэлхээ дээрх бүх хуваарилалтыг хянадаг нягтлан бодох бүртгэлийн үндсэн бүтэц. Энэ талбарт овоолгын мета өгөгдөл, чөлөөт жагсаалтын заагч, өөр өөр хуваарилалтын хэмжээтэй бингийн бүтэц орно. Хуваарилагч нь sbrk()-ээр програмын завсарлагаа сунгах ба эхний өргөтгөл нь M_TOP_PAD гэж нэрлэгддэг дотоод параметрээр зохицуулагддаг бөгөөд энэ нь анхдагчаар 128 КБ дүүргэлттэй байдаг. Гэсэн хэдий ч, бодит анхны хүсэлтийг хуудасны зэрэгцүүлэлт болон одоо байгаа завсарлагааны байрлалд тохируулсан байдаг бөгөөд энэ нь ихэвчлэн жижиг анхны хүсэлтийг үүсгэдэг бөгөөд энэ нь ихэвчлэн шинээр эхлүүлсэн процесс дээр 72 КБ хэмжээтэй ойролцоо буудаг.

Хоёрдугаарт, glibc 2.26-аас хойш хуваарилагч нь thread-local cache-г (tcache) эхний хэрэглээнд эхлүүлдэг. tcache нь 64 хогийн сав (жижиг хэмжээний ангилалд нэг) агуулах бөгөөд тус бүр нь 7 кэштэй хэсгийг хадгалах чадвартай. tcache_perthread_struct нь өөрөө ойролцоогоор 1 КБ зарцуулдаг боловч үүнийг эхлүүлэх үйлдэл нь илүү өргөн талбайн тохиргоог өдөөдөг. Гуравдугаарт, C++ ажиллах хугацаа нь таны main() ажиллахаас өмнө аль хэдийн хуваарилалтыг гүйцэтгэсэн байна — статик бүтээгчид, std::cout болон найзуудад зориулсан iostream буфер эхлүүлэх, локал тохиргоо зэрэг нь тэрхүү эхний овоолгын ул мөрийг бий болгоход хувь нэмэр оруулдаг.

Арена систем ба урьдчилсан хуваарилалт яагаад ухаалаг байдаг вэ

Санах ойн хэмжээг хэсэг хэсгээр нь шаардахын оронд тодорхой хэмжээний санах ойг урьдчилан хуваарилах шийдвэр гаргасан нь санамсаргүй хэрэг биш юм. Энэ нь олон арван жилийн системийн програмчлалын туршлагаас үндэслэсэн зориудаар хийгдсэн инженерийн солилцоо юм. brk() эсвэл mmap() руу хийх дуудлага бүр нь хэрэглэгчийн орон зайгаас цөмийн орон зай руу контекст шилжих, үйл явцын виртуал санах ойн зураглалыг өөрчлөх, хуудасны хүснэгтийн боломжит шинэчлэлтүүдийг агуулдаг. Орчин үеийн техник хангамжид нэг системийн дуудлага нь ойролцоогоор 100-200 наносекундын зардалтай байдаг. Энэ нь тусад нь авч үзэхэд өчүүхэн төдий бөгөөд масштабаар нь сүйрлийн үр дагаварт хүргэдэг.

Эхлүүлэх явцад 10,000 жижиг хуваарилалт хийдэг программыг авч үзье. Урьдчилан хуваарилахгүйгээр энэ нь 10,000 системийн дуудлага гэсэн үг бөгөөд ойролцоогоор 1-2 миллисекунд цэвэр нэмэлт зардал шаардагдана. Аренад суурилсан хуваарилагчийн тусламжтайгаар эхний хуваарилалт нь нэг системийн дуудлагыг өдөөж, дараачийн 9,999 хуваарилалт нь заагч арифметик болон холбосон жагсаалтын үйлдлүүдийн тусламжтайгаар хэрэглэгчийн орон зайд бүхэлдээ үйлчилдэг бөгөөд тус бүр нь ойролцоогоор 10-50 нано секунд зарцуулдаг. Математик нь хоёрдмол утгагүй: урьдчилсан хуваарилалт нь дарааллаар ялдаг.

Таны эхний хуваарилалт дээр харагдах 72 КБ санах ой нь дэмий үрсэн санах ой биш бөгөөд энэ нь гүйцэтгэлийн хөрөнгө оруулалт юм. Хуваарилагч таны хөтөлбөр удахгүй илүү их хуваарилалт хийх болно гэж бооцоо тавьж байгаа бөгөөд бодит амьдрал дээрх бүх хувилбарт энэ бооцоо сайн үр дүнд хүрнэ. Орчин үеийн 64 битийн системд ашиглагдаагүй виртуал хаягийн орон зайн үнэ үндсэндээ тэг байна.

Виртуал санах ой ба физик санах ой: Энэ яагаад хамаагүй вэ

Иймэрхүү үйлдэлтэй анх удаа тулгарсан хөгжүүлэгчдэд санаа зовдог нийтлэг асуудал бол нөөцийн хаягдал юм. Хэрэв надад ердөө 4 байт хэрэгтэй бол миний програм яагаад 72 KB зарцуулж байна вэ? Чухал ойлголт бол виртуал санах ой нь физик санах ой биш юм. glibc нь програмын завсарлагааны хугацааг 72 КБ-аар сунгах үед цөм нь процессын виртуал санах ойн зураглалыг шинэчилдэг боловч тэдгээр хуудсуудыг RAM-аар шууд буцааж өгдөггүй. Бодит биет хуудсууд нь хуудасны алдаа-аар дамжуулан хүсэлтийн дагуу хуваарилагддаг — зөвхөн таны програм тодорхой хаяг руу бичих үед цөм түүнд санах ойн бодит хуудсыг оноодог.

💡 DID YOU KNOW?

Mewayz replaces 8+ business tools in one platform

CRM · Invoicing · HR · Projects · Booking · eCommerce · POS · Analytics. Free forever plan available.

Start Free →

Энэ нь хэдийгээр таны процессын виртуал хэмжээ 72 КБ-аар нэмэгдэж байгаа ч түүний оршин суугч тохируулгын хэмжээ (RSS) буюу бодит хэрэглэгдэж буй RAM-ийн хэмжээ нь зөвхөн таны хүрч буй хуудсуудаар нэмэгддэг гэсэн үг юм. Ганц шинэ int-ийн хувьд энэ нь ихэвчлэн нэг 4 КБ хуудас, дээр нь аренагийн мета өгөгдөл ямар ч хуудас эзэлж байна. Үлдсэн виртуал орон зай нь ашиглахад бэлэн, хаягийн зайнаас өөр зардал шаарддаггүй бөгөөд үүнээс танд 64 битийн Линукс систем дээр 128 TB байна.

Үйлдвэрлэлийн программуудыг профайл үүсгэх, хянах үед энэ ялгаа нь чухал юм. Хэрэв та бодит нөөцийн хэрэглээг хянах шаардлагатай программ хангамжийг бүтээж байгаа бол - энэ нь SaaS-ийн нөөц, бичил үйлчилгээ эсвэл бизнесийн үйл ажиллагаанд зориулсан Mewayz гэх мэт платформ дээр ажилладаг аналитик дамжуулах хоолой эсэхээс үл хамааран виртуал хэмжээнээс илүү RSS-г үргэлж хянах хэрэгтэй. /proc/[pid]/smaps, valgrind --tool=massif, pmap зэрэг хэрэгслүүд нь виртуал санах ойн тоон үзүүлэлтүүдийг төөрөгдүүлэхийн оронд танд бодит санах ойн мөрийг өгч чадна.

Өөр өөр хуваарилагчид эхний хуваарилалтыг хэрхэн зохицуулдаг вэ

72 КБ-ын хэмжээ нь glibc-ийн ptmalloc2-д зориулагдсан. Бусад хуваарилагчид өөр өөр сонголт хийдэг бөгөөд эхний хуваарилалтын нэмэгдэл зардал нь үүнээс хамаарч өөр өөр байдаг. Эдгээр ялгааг ойлгох нь гүйцэтгэлд мэдрэмтгий програмуудад хуваарилагчийг сонгоход чухал ач холбогдолтой.

  • jemalloc (Facebook, FreeBSD ашигладаг) — Thread-local caches бүхий илүү нарийн ширхэгтэй арена бүтцийг ашигладаг. Эхний нэмэлт зардал нь илүү өндөр (ихэвчлэн 200+ КБ) байх хандлагатай боловч түгжээний маргаан багассан тул олон урсгалтай гүйцэтгэлийг илүү сайн хангадаг.
  • tcmalloc (Google-н Thread-Caching Malloc) — Урьдчилан түрэмгий байдлаар хуваарилах замаар урсгал бүрт ойролцоогоор 2 МБ кэшийг хуваарилдаг. Эхний нэмэлт зардал өндөр боловч дараагийн жижиг хуваарилалт нь маш хурдан байдаг.
  • musl libc's malloc — Бүх хуваарилалтад mmap-д суурилсан илүү энгийн загварыг ашигладаг. Эхний нэмэлт зардал нь хамгийн бага (ихэвчлэн хуваарилалт бүрт ердөө 4 КБ байдаг) боловч системийн дуудлага илүү их байдаг тул хуваарилалтын зардал өндөр байдаг.
  • mimalloc (Microsoft) — 64 МБ сегмент бүхий сегментэд суурилсан хуваарилалтыг ашигладаг. Эхний хуваарилалт нь 64 МБ виртуал захиалгыг (хамгийн бага физик үүрэг хариуцлагатай), онцгой байршил, дамжуулах чадварын хувьд арилжааны хаягийн зайг идэвхжүүлдэг.

Эдгээр хуваарилагчийн хоорондох сонголт нь таны ажлын ачааллаас бүрэн хамаарна. Хүнд олон урсгалтай хуваарилалт бүхий урт хугацааны серверийн програмуудын хувьд jemalloc эсвэл tcmalloc нь ихэвчлэн glibc-ийн анхдагчаас илүү ажилладаг. Санах ой хязгаарлагдмал суулгагдсан системүүдийн хувьд дамжуулах чадвар бага ч гэсэн musl-ийн энгийн аргыг илүүд үзэж болно. Ихэнх ерөнхий зориулалттай ширээний компьютер болон серверийн програмуудын хувьд ptmalloc2-ийн 72 КБ-ын эхний нэмэлт зардал нь тааруулахгүйгээр сайн ажилладаг боломжийн өгөгдмөл юм.

Анхны хуваарилалтын зан үйлийг тохируулах

Хэрэв өгөгдмөл 72 КБ-ын анхны нэмэлт зардал нь таны хэрэглээний хувьд үнэхээр асуудалтай байгаа бол - магадгүй та хэдэн мянган богино хугацааны процессуудыг үүсгэж байгаа бөгөөд тус бүр нь цөөхөн хуваарилалт хийдэг - glibc нь mallopt() болон MALLOC_ гэр бүлийн орчны хувьсагч

аар дамжуулан хэд хэдэн тохируулагчийг хангадаг.

M_TOP_PAD параметр нь хуваарилагч нэн даруй шаардлагатай хэмжээнээс илүү хэр хэмжээний нэмэлт санах ой шаардахыг хянадаг. Үүнийг mallopt(M_TOP_PAD, 0)-ээр 0 болгож тохируулах нь хуваарилагчаас зөвхөн шаардлагатай зүйлийг л хүсэхийг хэлж, эхний нэмэлт зардлыг мэдэгдэхүйц бууруулна. M_MMAP_THRESHOLD параметр нь дээрх хуваарилалтууд талбайн оронд mmap-г ашигладаг хэмжээг хянадаг. M_TRIM_THRESHOLD нь суллагдсан санах ойг үйлдлийн систем рүү буцаах үед хянадаг. Мөн glibc 2.26-с хойш glibc.malloc.tcache_count болон glibc.malloc.tcache_max тохируулагч нь танд урсгалын кэшийн ажиллагааг хянах боломжийг олгоно.

Гэсэн хэдий ч, анхааруулах үг: эдгээр параметрүүдийг сайтар харьцуулахгүйгээр тааруулах нь бараг үргэлж байдлыг улам дордуулдаг. Өгөгдмөлүүдийг бодит ертөнцийн өргөн цар хүрээтэй профайл дээр үндэслэн сонгосон бөгөөд тэдгээр нь ажлын ачааллын дийлэнх хувийг эзэлдэг. Хэрэв танд malloc-ийн нэмэлт зардал нь саад тотгор учруулдаг гэсэн баттай нотолгоо байхгүй бол та өөрчлөлтийнхөө нөлөөг хэмжээгүй бол анхдагч тохиргоог орхи. Хуваарилагчийг хугацаанаас нь өмнө оновчтой болгох нь сарлагийн сахлын маш нууцлаг хэлбэр бөгөөд тоо томшгүй олон инженерийн цаг зарцуулж, үл тоомсорлодог.

Энэ нь бидэнд системийн програмчлалын талаар юу заадаг вэ

72 КБ-ын эхний хуваарилалтын нууц нь үндсэндээ хийсвэрлэлийн давхаргуудын тухай сургамж юм. C++ нь танд new int нь 4 байт хуваарилдаг гэсэн хуурмаг ойлголтыг өгдөг. Хэлний стандартад ингэж заасан байдаг. Таны оюун санааны загвар ингэж хэлж байна. Гэхдээ таны код болон техник хангамжийн хооронд C++ ажиллах хугацаа, Си номын сангийн хуваарилагч, цөмийн виртуал санах ойн дэд систем, техник хангамжийн MMU болон TLB зэрэг олон нарийн төвөгтэй системүүд байрладаг бөгөөд тэдгээр нь тус бүр өөрийн зан төлөв, оновчлол, нэмэлт зардлыг нэмдэг.

Энэ бол дутагдал биш. Энэ бол системийн програм хангамжийн бүхэл бүтэн цэг юм. Давхарга бүр бодит асуудлыг шийдэхийн тулд байдаг: хуваарилагч байдаг тул та хуваарилалт бүрт системийн дуудлага хийх шаардлагагүй болно. Виртуал санах ойн систем байгаа тул та физик санах ойг шууд удирдах шаардлагагүй болно. Хуудасны алдаа гаргагч байдаг тул санах ойг залхуу, үр дүнтэй ажиллуулдаг. Давхарга бүр их хэмжээний гүйцэтгэл, тав тухтай байдлыг хангахын тулд бага хэмжээний ил тод байдлыг арилгадаг.

Хамгийн найдвартай, өндөр гүйцэтгэлтэй системийг бүтээгчид бол эдгээр давхаргуудыг ойлгодог хүмүүс бөгөөд тэдгээр нь тэдний талаар байнга бодож байх шаардлагатай биш, харин гэнэтийн зүйл тохиолдоход (нууцлагдмал 72 КБ-ын хуваарилалт гэх мэт) учир шалтгааныг ойлгох оюун санааны загвартай байдаг. Бодит цагийн арилжааны систем, тоглоомын хөдөлгүүр эсвэл олон мянган хэрэглэгчдэд үйлчилдэг бизнесийн платформ байгуулж байгаа эсэхээс үл хамааран таны код системийн түвшинд юу хийдэг талаар дүгнэлт хийх чадвар нь чадварлаг хөгжүүлэгчдийг онцгой хүмүүсээс ялгадаг. 72 KB нь алдаа биш юм. Энэ бол таны хуваарилагч ажлаа гайхалтай хийж байна.

Өнөөдөр бизнесийн үйлдлийн системээ байгуулаарай

Чөлөөт ажилчдаас эхлээд агентлаг хүртэл Mewayz нь 207 нэгдсэн модулиудаар 138,000 гаруй бизнесийг эрхэлдэг. Үнэгүй эхлүүлээрэй, өсөх үедээ шинэчилнэ үү.

Үнэгүй бүртгэл үүсгэх→

Try Mewayz Free

All-in-one platform for CRM, invoicing, projects, HR & more. No credit card required.

Start managing your business smarter today

Join 30,000+ businesses. Free forever plan · No credit card required.

Ready to put this into practice?

Join 30,000+ businesses using Mewayz. Free forever plan — no credit card required.

Start Free Trial →

Ready to take action?

Start your free Mewayz trial today

All-in-one business platform. No credit card required.

Start Free →

14-day free trial · No credit card · Cancel anytime