Ок, відкрив рандомний публічний хедер (code.dpdk.org/..._eal/include/rte_bitmap.h) — є багато static inline (те, про що писалось вище). Так, я не бачу способу обернути це в Rust. Але я залишаюсь на позиції, шо це резонне обмеження. rustc не компілює С код.
Гіпотетично, шоб це працювало автоматично, то треба, шоб умовно якись bindgen розпарсив хедер, видалив static, скомпілював хедер без static як *.с файл С компілятором, прописав прапори лінковки до скомпільованого obj (навіть не знаю куди, якось так шоб їх було зручно включити в build.rs напевно). І при цьому треба ще якось сек’юрно аугментувати імена цих функцій, бо тепер вони глобальні і можуть конфліктувати з іншими....
Думаю, набагато резонніше вимагати від програміста, який пише обгортку, шоб він переписував функції, реалізовані в хедерах, на Rust вручну. В Python і C# така ж позиція в цьому, наскільки я знаю. Цікаво, чи хоч якась мова, синтаксис якої не сумісний з С, вирішує це краще?)
Куча библиотек предоставляют свои функции в *.h файле как static.
А можна якісь посилання на приклади?
Я можу щось упускати, але припускаю 2 причини так робити:
1. Якшо функції прямо в хедері і реалізовані (e.g. single-header бібліотека, static inline і т.д.) і по якимось причинам не хочеться, шоб ці функції експортувались за межі файлу, де вона інклудиться — ну так хедер ви ж все-рівно не перевикористовуєте в Rust, а описуєте всі деклараці в Rust-коді. Ну тобто, так, rustc не компілює С-шний код, але хіба це не резонно?
2. Якшо хедер хоче задати якийсь єдиний інтерфейс для функції, але кожен *.c файл, який його інклудить повинен реалізувати цю функцію самостійно — ну тоді це і не публічна функція бібліотеки, і не треба шоб FFI мав до неї доступ. І таке є сенс робити тільки в приватних хедерах.
Я розумію про що ви говорите з обгортками типів (правда, ваш конкретний приклад виглядає дуже нереалістично, можу пояснитись; якщо це справжній код, було б цікаво дізнатись деталі). В мене в подібних ситуаціях зазвичай виявлялось, що я не враховував якихось дрібниць, які потім могли б вилитись в складні баги, і borrow checker був правий, він просто змушував мене структурувати і типізувати дані правильно відразу. З часом в мене випрацювалась деяка інтуїція, і я став витрачати на це менше часу.
Я пригадую, в інтернетах натикався на випадки, де borrow checker, будучи недостатньо розумним, матюкався на повністю валідний з точки зору власності код, але це буває рідко. По-моєму, я це бачив ще до NLL borrow-checker’а, який ввімкнений за замовчуванням ще з Rust 1.31.
Про static функції я теж не зрозумів. Чому FFI повинен вміти викликати функції, явно позначені як приватні в межах свого файлу (юніту трансляції)?
Я помічаю подібну тенденцію. Але на щастя виключень вистачає, щоб мова розвивалась в напрямку покриття ніши С++. Я теж прийшов в Rust з C++. ІМХО, вивчення Rust і розвиток інтуїції в ньому допомогли мені писати кращий С++ код: думати концепціями володіння і тривалості життя об’єктів дуже зручно і там.
Думаю для матриць матлаб ініціалізує пам’ять відразу коли алокує, тому навряд там можна чистий експеримент поставити. Але хз, я не шарю матлаб.
Але повторю мій основний пойнт, не обмежувати алокації розміром фізичної пам’яті — це дуже практично, бо програми майже завжди алокують значно більше, ніж використовують. Це добре видно в значеннях VIRT vs RES в top.
Думаю, це переважно наслідок динамічних структур даних: наприклад, створюєш ти vector в C++, кладеш туди 3 елементи, а алокується відразу на 100, добив до 100 — реалокувалось до 1000 (це пальцем в небо, я не знаю точних чисел). Це оптимізація швидкодії, шоб не робити реалокацію на кожен push. А так як динамічні структури даних використовуються всюди, в більш високорівневих мовах навіть немає масивів статичного розміру, то так в середньому і виходить: програма займає X байт в пам’яті, при тому, шо алокувала вона 10X. І якби менеджер пам’яті не дозволяв алокації понад фізично доступну пам’ять, то використати можна було б тільки її 1/10.
Я майже впевнений, шо Windows/MacOS теж не обмежують алокації розміром фізичної пам’яті (не бачу іншого способу утилізувати всю пам’ять в наших реаліях), тільки напевно ООМ всюди по різному обробляється.
UPD: Якшо комусь не лінь, запустіть мій С-шний код з попереднього коментаря на Windows/MacOS і гляньте, чи є «Allocation failed» в логах (я майже впевнений, шо він не повішає систему — або сам впаде, або без проблем алокує 1ТБ і все буде добре, але на всяк збережіть все важливе). For the sake of science, так би мовити.
Ось так я тільки шо алокував терабайт при моїх 8ГБ без свопа: pastebin.com/NmNtkcFL
postimg.cc/HJjrQKd7
Дякую! Хороша і потрібна стаття!
Я вже довго живу тільки на GNU/Linux і втратив скіл об’єктивно описувати переваги і недоліки порівняно з іншими ОС (тільки Windows в моєму випадку), бо просто забув як там все, забув проблеми пов’язані з переходом. Найбільше людей спробувати Linux я надихнув якраз протягом свого першого року.
когда я случайно запрошу дохулиард мегабайтов оно не пыталось их искать, а грило мне, что я дурак
Воно не скаже, Linux не відмовляє в алокаціях через нестачу пам’яті. Трохи вище описав детальніше.
Своп юзается только тогда, когда памяти начинает не хватать.
Це теж не зовсім так. Агресивність використання свопа залежить від значення swappiness
Хочу вставити свої 5 копійок в дискусію. Те, шо прога віджирає 16ГБ пам’яті — це звісно проблема цієї проги, але те, шо від цього намертво висне ОС — проблема ОС. Я die-hard фанат GNU/Linux, сам не раз натикався на цю проблему. TL;DR: допоміг earlyoom, все буде добре.
Чому так відбувається? Linux за замовчуванням не відмовляє в алокаціях пам’яті через її можливу нестачу. Процес може успішно алокувати 100ГБ віртуальної пам’яті, навіть якшо машина має тільки 8ГБ. Поки він не почне по факту використовувати більше, ніж доступно — все ок. Іншими словами, malloc на 100ГБ не поверне NULL, а от ініціалізація цього масива вже призведе до проблем.
На перший погляд це може звучати дуже нелогічно, але насправді програми в середньому алокують значно більше пам’яті ніж використовують (через динамічні структури даних в першу чергу). Тому це прагматично. Якби кожна алокація падала від нестачі гарантовано доступної пам’яті, в нас би починав падати софт від нестачі пам’яті ше при її утилізації в
Що ж робити, коли фізичної пам’яті таки не вистачає? В таких випадках запускається OOM (out of memory) killer і вбиває процес, який на його думку спричиняє найбільше проблем і одночасно не дуже важливий. Там якісь свої евристики, не просто «хто зжер найбільше».
Проблема в тому, шо якшо пам’ять закінчується швидше, ніж OOM killer встигає відпрацювати — система висне.
Ніби можна налаштувати OOM killer, щоб він поводився більш агресивно, деталей я не знаю. Але наскільки я пам’ятаю, це матиме якісь інші негативні наслідки. Компроміс.
Earlyoom — це демон, який може зреагувати на OOM раніше (в причини я не вникав), тому цю ситуацію він вирішує. Fedora недавно анонсували, що включать його в наступний реліз за замовчуванням. А Ленарт Поттерінг запропонував включити oomd (теж ранній OOM демон, від Facebook) в Systemd. Тому через певний час це буде в більшості дистрибутивів і можна буде не переживати за це.
Буду вдячний за виправлення неточностей.
Як Windows обробляє подібні ситуації я не знаю. Скоріше всього там теж можна алокувати більше ніж доступно, це було б логічно, але я не перевіряв (напишіть, хто знає). Але я б не писав такі грубі твердження, що «X управляє пам’ятю краще ніж Y» без вникання в деталі. Найімовірніше, різниця в компромісах.
Є щорічний StackOverflow Developer Survey, там трохи інші показники, але він напевно найпопулярніший в світі. Ось за 2019: insights.stackoverflow.com/survey/2019
Прям логічне продовження комікса з статті)
Мені теж було б простіше допомогти через Paypal. Якщо така можливість з’явиться, відпишіться, будь ласка. gofundme.com не приймає мою китайську карту UnionPay
Я теж на цьому застопорився спочатку. Там перший раз «на момент переїзду», а другий — «поточне». Підказка «скіпніть, якшо не змінилось» допомогла б)
www.facebook.com/events/1825587251017070
Друзі, оскільки приміщення, де буде проведена зустріч, має обмеження, то можлива така ситуація, що ми будемо вимушені закрити реєстрацію до дедлайну — при реєстрації критичної кількості людей.
Да, именно там, где указано на карте. Вход со стороны дома № 136. Обращайтесь, если нужно подсказать, как проехать.
Але справжня причина, чому ми вибрали Вінницю заключається в тому, шо всі організатори живуть в Вінниці)
Так, я теж трохи сумніваюсь в адекватності оцінки екології. По-перше, більшість показників тут рахуються по області: наприклад, теоретично, якийсь завод чи заповідник на півдні Хмельницької області більше впливав би на екологію Чернівців ніж Хмельницького, але порахований він буде до Хмельницького. По-друге, абсолютна і відносна площа заповідників в області сильно корелюють, але враховані як два незалежних показника.