Найти в Дзене
Покупайте СтеллыИ дарите их за контент
3 дня назад
 • Вы подписаны

Как держать десятки тысяч открытых соединений и при этом не нагружать CPU?

https://gitverse.ru/nicktretyakov1/RustML Для того чтобы не крутить бесконечный while-цикл, постоянно вызывая poll() у всех Future. Нужно использовать связку Executor + Reactor + Waker. Если бы Executor просто в цикле делал: loop { for future in all_futures { future.poll(...); } } то при тысячах задач, большинство из которых ждут сеть/диск, CPU бы сгорал впустую на 100 %. Это особенно плохо и для обычных серверов, и для задач, где рядом крутятся тяжёлые вычисления (в т...

6 дней назад
 • Вы подписаны

async/await это Enum

Когда вы пишете async fn, компилятор превращает функцию в структуру (или enum), которая реализует Future. Этот enum хранит: // То, что пишет программист async fn fetch_data(url: String) -> Result<Data, Error> { let req = build_request(&url); // локальная переменная let resp = client.send(req).await?; // ← точка приостановки let data = process(resp).await?; // ← ещё одна Ok(data) } Компилятор примерно генерирует такое: enum FetchDataStateMachine { // Начальное состояние (до первого await) Start { url: String, // захваченные параметры }, // После первого ...

1 неделя назад
 • Вы подписаны

Portable SIMD даёт большой выигрыш в ML

Portable SIMD в Rust — это абстракция над SIMD-инструкциями (Single Instruction, Multiple Data), которая позволяет писать код с «широкими» типами (f32x4, f32x8, f32x16 и т.д.), а компилятор/LLVM сам выбирает лучшие инструкции целевой архитектуры (AVX2/AVX-512 на x86, NEON на ARM, SIMD128 на WASM и т.д.). Portable SIMD (особенно std::simd на nightly или fearless_simd на stable) — это самый чистый и безопасный способ написания кода для CPU-инференса и предобработки в Rust. Он идеально подходит для: Для больших матриц всё равно лучше опираться на хорошо оттюненный BLAS или специализированные тайловые ядра, а Portable SIMD использовать внутри этих ядер или для всего остального...

2 недели назад
 • Вы подписаны

SIMD в машинном обучении: как заставить LLVM работать за вас

90% ML-кода на Rust не требует ни unsafe, ни std::arch, ни интринсиков. Нужно лишь понимать, что мешает авто-векторизации, и убирать эти препятствия. Ниже — подробный разбор с реальными паттернами для ML. LLVM проходит по циклу и пытается доказать, что итерации независимы: Если всё сходится — LLVM генерирует «vectorized loop» + «scalar epilogue» для хвоста. pub fn add_arrays(a: &[f32], b: &[f32], out: &mut [f32]) { for i in 0..a.len() { out[i] = a[i] + b[i]; } } На x86_64 с -C opt-level=3 LLVM сгенерирует SSE2 (addps) — по 4 f32 за инструкцию. Проверить можно через cargo asm или godbolt...

2 недели назад
 • Вы подписаны

std::arch для ML

Для 90% ML-задач в Rust лучше использовать — faer, candle, burn, ndarray с matrixmultiply, llama.cpp биндинги. Поскольку уже содержат оптимизированные SIMD-ядра, runtime-диспетчеризацию и протестированы на десятках платформ. std::arch стоит использовать, когда вы пишете свой inference-движок, исследовательский прототип с нестандартными операциями, или оптимизируете конкретное ядро, которое библиотеки не покрывают. std::arch — это модуль стандартной библиотеки Rust, дающий прямой доступ к интринсикам (intrinsics) — функциям, которые компилируются в конкретные инструкции процессора (SIMD, FMA, крипто, битовые операции)...

3 недели назад
 • Вы подписаны

Как заменить ветвление в ML (branchless)

let result = if condition { a } else { b }; Компилятор обычно генерирует JMP / JNE / JLE. Когда условие почти случайное (сравнения, выбор между двумя значениями), Branch Prediction Unit постоянно ошибается → pipeline flush → сильное замедление. В Rust bool можно безопасно привести к целому: // Выбираем a, если condition == true, иначе b let result = a * (condition as i32) + b * (!condition as i32); Или чуть аккуратнее (избегаем лишнего отрицания): let mask = condition as i32; // 0 или 1 let result = a * mask + b * (1 - mask); Для f32/f64 то же самое: let mask = condition as f32; // 0...

Покупайте СтеллыИ дарите их за контент