uk
Feedback
Блог*

Блог*

Відкрити в Telegram

Блог со звёздочкой. Много репостов, немножко программирования. Небольшое прикольное комьюнити: @decltype_chat_ptr_t Автор: @insert_reference_here

Показати більше
1 921
Підписники
-224 години
-37 днів
-1530 день
Архів дописів
Табы или пробелы?
Anonymous voting

photo content

Иногда кажется, что взрослая жизнь – это детский сад с добавкой кофеина. Мы все тут взрослые, но хотим вечернее печенье и спать с плюшевым мишкой

открытка @hayork
открытка @hayork

#meme про... Бомжей

Что ж. Финальный босс, кстати, чёт довольно простой
Что ж. Финальный босс, кстати, чёт довольно простой

#prog #rust #article Exploring the Rust compiler benchmark suite Статья о том, как устроен бенчмарк для измерения производительности компиляции rustc и о том, как он интегрирован с общим процессом разработки

Пугающе правдоподобно

How would you call a person whose name appears in a questionnaire? An in-quiz-itor

Вероятно, шоу "Кто хочет стать миллионером" не очень популярно в Зимбабве

Не инцест, а связь с предками

Что ж, если ограничиться отклонениями в ±2 сигмы, то, в принципе, похоже

photo content

И ещё: если сначала вызывать calloc, а потом malloc, то разница по времени становится больше, но общая картина не меняется

#prog Подписчики, я обескуражен. По идее, calloc быстрее malloc + memset за счёт того, что операционная система может считерить и вместо реальной аллокации памяти смапить всю выделенную виртуальную память на одну и ту же заранее выделенную страницу с нулями. С другой стороны, при последующей работе обращение к странице вызовет дорогостоящий page fault, который заставит операционную систему реально выделить память. Я решил замерить разницу при помощи кода, который для нескольких количеств страниц выделяет память: сначала при помощи calloc и читает по первому байту из каждой выделенной страницы, а потом при помощи malloc и перезаписывает всё нулями. Код выглядит так:
fn get_page_size() -> usize {
    // платформо-специфичный код
}

use std::alloc::{alloc, alloc_zeroed, dealloc, Layout};
use std::time::Instant;

fn main() {
    let page_size = get_page_size();
    println!("page size = {page_size} bytes\n");

    for n_pages in (0..5).map(|p| 2 * 10_usize.pow(p)) {
        let layout = Layout::from_size_align(page_size * n_pages, 1).unwrap();
        println!("n pages = {n_pages}");

        let start = Instant::now();
        let ptr = unsafe { alloc(layout) };
        assert!(!ptr.is_null());
        unsafe {
            std::hint::black_box(ptr).write_bytes(0, layout.size());
        }
        unsafe { dealloc(ptr, layout) }
        let duration = start.elapsed();
        println!("with alloc + memset:\t{duration:?}");

        let start = Instant::now();
        let ptr = unsafe { alloc_zeroed(layout) };
        assert!(!ptr.is_null());
        std::hint::black_box(ptr);
        for n in 0..n_pages {
            std::hint::black_box(unsafe { ptr.add(n * page_size).read() });
        }
        unsafe { dealloc(ptr, layout) }
        let duration = start.elapsed();
        println!("with calloc:\t\t{duration:?}");

        println!();
    }
}

Когда я запускаю этот код на Rust playground (который, я напомню, на Linux), я получаю такие результаты (примерно, потому что конкретные цифры от запуска к запуску, разумеется, разнятся): n pages = 2 with alloc + memset: 4.061µs with calloc: 660ns n pages = 20 with alloc + memset: 28.651µs with calloc: 2.27µs n pages = 200 with alloc + memset: 728.031µs with calloc: 236.287µs n pages = 2000 with alloc + memset: 3.009318ms with calloc: 1.227636ms n pages = 20000 with alloc + memset: 27.395091ms with calloc: 9.131857ms Видно, что calloc хоть и явно не бесплатный (даже не смотря на то, что лишь читаем, а не пишем), но всё равно быстрее malloc + memset даже на двух страницах памяти. А вот какой результат я получаю на своём ноутбуке, который на Windows:
n pages = 2
with alloc + memset:    11.3µs
with calloc:            1.5µs

n pages = 20
with alloc + memset:    38.4µs
with calloc:            4.7µs

n pages = 200
with alloc + memset:    392.2µs
with calloc:            55.5µs

n pages = 2000
with alloc + memset:    2.6747ms
with calloc:            1.8153ms

n pages = 20000
with alloc + memset:    37.8768ms
with calloc:            24.9391ms

Видно, что calloc и тут быстрее, но уже далеко не так сильно. Более того, если выделять по 200 000 страниц памяти (что не получается сделать на playground из-за квот по памяти, видимо), то получается что-то вроде такого:
n pages = 200000
with alloc + memset:    345.1817ms
with calloc:            318.5761ms

То есть относительная разница, кажется, стремится к нулю (а в некоторых запусках calloc даже медленнее). Посему вопрос: откуда такая разница в поведении? Существенна ли тут разница в OS или ещё играет роль (очевидная) разница в железе? Размер страниц памяти, если что, одинаковый, я проверял.

Repost from PB
мужчинам нужно обещать весь мир и дарить цветочки, мороженое и оргазм.