Быстрый способ обнулить блок памяти?
От: nbie  
Дата: 10.09.11 09:08
Оценка:
Добрый день, коллеги.
Подскажите самый быстрый способ обнулить блок памяти (1000000 байт)?

PS Кроме SSE инструкций (заполнять по 16 байт) ничего нет?
Re: Быстрый способ обнулить блок памяти?
От: Аноним  
Дата: 10.09.11 09:11
Оценка:
Здравствуйте, nbie, Вы писали:

N>Добрый день, коллеги.

N>Подскажите самый быстрый способ обнулить блок памяти (1000000 байт)?

N>PS Кроме SSE инструкций (заполнять по 16 байт) ничего нет?


А что за ОС?
В Линукс можно выполнить mmap() нужного размера куска файла /dev/zero в память.
Re[2]: Быстрый способ обнулить блок памяти?
От: nbie  
Дата: 10.09.11 09:17
Оценка:
А>А что за ОС?
А>В Линукс можно выполнить mmap() нужного размера куска файла /dev/zero в память.

Пардон, Windows.

PS Но если говорить про linux: за счет чего такая операция имеет выигрыш производительности? Разве работа функции не сводится к побайтовому копированию или блочному по 16?
Re[3]: Быстрый способ обнулить блок памяти?
От: dilmah США  
Дата: 10.09.11 09:21
Оценка:
N>PS Но если говорить про linux: за счет чего такая операция имеет выигрыш производительности? Разве работа функции не сводится к побайтовому копированию или блочному по 16?

за счет откладывания уплаты стоимости на момент(ы) первого доступа к этой памяти
Re[4]: Быстрый способ обнулить блок памяти?
От: nbie  
Дата: 10.09.11 09:27
Оценка:
N>>PS Но если говорить про linux: за счет чего такая операция имеет выигрыш производительности? Разве работа функции не сводится к побайтовому копированию или блочному по 16?
D>за счет откладывания уплаты стоимости на момент(ы) первого доступа к этой памяти

Очень интересно. Подобного в Windows нет?
Могли бы сказать ключевые слова для поиска инф, чтобы понять смысл этих слов? ) Или разъяснить.
Re[5]: Быстрый способ обнулить блок памяти?
От: dilmah США  
Дата: 10.09.11 09:56
Оценка: 3 (2)
D>>за счет откладывания уплаты стоимости на момент(ы) первого доступа к этой памяти

N>Очень интересно. Подобного в Windows нет?

N>Могли бы сказать ключевые слова для поиска инф, чтобы понять смысл этих слов? ) Или разъяснить.

http://en.wikipedia.org/wiki/Memory_management_unit

примерно по тем же принципам по которым работает своп.
Современные процессоры автоматически отображают виртуальные адреса в физические. Если код пытается обратиться по виртуальному адресу который ни на что не отображается, то происходит trap и управление передается ОС. ОС смотрит что такое, и может разрешить это обращение, настроив отображение для этого адреса (для этой страницы памяти)

Когда ты делаешь mmap на /dev/zero то тебе просто выдают указатель на неициализированную память (которая не отображена ни на какие реальные адреса). Когда ты пытаешься обратится к ней, то срабатывает ловушка и ОС выделяет страницу памяти заполненную нулями.
Re[6]: Быстрый способ обнулить блок памяти?
От: Pzz Россия https://github.com/alexpevzner
Дата: 10.09.11 10:51
Оценка: +1
Здравствуйте, dilmah, Вы писали:

D>Когда ты делаешь mmap на /dev/zero то тебе просто выдают указатель на неициализированную память (которая не отображена ни на какие реальные адреса). Когда ты пытаешься обратится к ней, то срабатывает ловушка и ОС выделяет страницу памяти заполненную нулями.


Угу. Иными словами, к цене memset() добавляется цена обработки (аппаратного) исключения.
Re: Быстрый способ обнулить блок памяти?
От: Pzz Россия https://github.com/alexpevzner
Дата: 10.09.11 10:54
Оценка: 1 (1)
Здравствуйте, nbie, Вы писали:

N>Подскажите самый быстрый способ обнулить блок памяти (1000000 байт)?


Я бы начал с memset(), собрав программу под соответствующий процессор (а не под generic i386), и разрешив компилятору инлайнить такие функции. memset() не так уж наивно устроен. Потом я бы померил получившуюся скорость, сравнил бы ее с теоретическим пределом, и либо успокоился, либо сел бы думать дальше.
Re[2]: Быстрый способ обнулить блок памяти?
От: Pavel Dvorkin Россия  
Дата: 10.09.11 11:21
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Здравствуйте, nbie, Вы писали:


N>>Подскажите самый быстрый способ обнулить блок памяти (1000000 байт)?


Pzz>Я бы начал с memset(), собрав программу под соответствующий процессор (а не под generic i386), и разрешив компилятору инлайнить такие функции. memset() не так уж наивно устроен. Потом я бы померил получившуюся скорость, сравнил бы ее с теоретическим пределом, и либо успокоился, либо сел бы думать дальше.


memset внутри себя вызывает SSE2 в определенных случаях. Случай ТС как раз такой. Поэтому имеет смысл попробовать SSE2 напрямую — обойтись без лишних проверок (а у ТС размер массива кратен 4). Будет ли эффект — трудно сказать.

Насчет инлайнить — можн поподробнее ? Трассировка в режиме релиз показывает, что она вызывается из библиотеки.
With best regards
Pavel Dvorkin
Re[3]: Быстрый способ обнулить блок памяти?
От: Pzz Россия https://github.com/alexpevzner
Дата: 10.09.11 12:13
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>memset внутри себя вызывает SSE2 в определенных случаях. Случай ТС как раз такой. Поэтому имеет смысл попробовать SSE2 напрямую — обойтись без лишних проверок (а у ТС размер массива кратен 4). Будет ли эффект — трудно сказать.


При таком размере накладные расходы от этих проверок — копейки. Я бы не стал тратить время на возню с SSE, если memset достаточно хорош.

PD>Насчет инлайнить — можн поподробнее ? Трассировка в режиме релиз показывает, что она вызывается из библиотеки.


Это от компилятора зависит. gcc инлайнит эти функции, если оптимизация включена. Насчет MSVC я не особенно копенгаген . Смотрите здесь: http://msdn.microsoft.com/en-us/library/26td21ds.aspx
Re[3]: Быстрый способ обнулить блок памяти?
От: nbie  
Дата: 10.09.11 12:15
Оценка:
N>>>Подскажите самый быстрый способ обнулить блок памяти (1000000 байт)?

Pzz>>Я бы начал с memset(), собрав программу под соответствующий процессор (а не под generic i386), и разрешив компилятору инлайнить такие функции. memset() не так уж наивно устроен. Потом я бы померил получившуюся скорость, сравнил бы ее с теоретическим пределом, и либо успокоился, либо сел бы думать дальше.


PD>memset внутри себя вызывает SSE2 в определенных случаях. Случай ТС как раз такой. Поэтому имеет смысл попробовать SSE2 напрямую — обойтись без лишних проверок (а у ТС размер массива кратен 4). Будет ли эффект — трудно сказать.


Присоединяюсь к вопросу. Если заполнение блоками по 16 байт — это максимум скорости, то проделать это самому в цикле разве не будет оптимальным?
PS Кстати, может кто сказать почему в SSE 16 максимум (?)? Почему не больше?
И, пардон, что такое "TC"?
Re[4]: Быстрый способ обнулить блок памяти?
От: Pavel Dvorkin Россия  
Дата: 10.09.11 12:23
Оценка:
Здравствуйте, nbie, Вы писали:

N>Присоединяюсь к вопросу. Если заполнение блоками по 16 байт — это максимум скорости, то проделать это самому в цикле разве не будет оптимальным?


Тот же memset, только без проверок на случай, если размер не кратен 16.

N>PS Кстати, может кто сказать почему в SSE 16 максимум (?)? Почему не больше?


16 * 8 = 128 — разрядность SSE

N>И, пардон, что такое "TC"?


Не что, а кто Topic Starter.
With best regards
Pavel Dvorkin
Re[4]: Быстрый способ обнулить блок памяти?
От: Pzz Россия https://github.com/alexpevzner
Дата: 10.09.11 12:23
Оценка:
Здравствуйте, nbie, Вы писали:

PD>>memset внутри себя вызывает SSE2 в определенных случаях. Случай ТС как раз такой. Поэтому имеет смысл попробовать SSE2 напрямую — обойтись без лишних проверок (а у ТС размер массива кратен 4). Будет ли эффект — трудно сказать.


N>Присоединяюсь к вопросу. Если заполнение блоками по 16 байт — это максимум скорости, то проделать это самому в цикле разве не будет оптимальным?


Это вы кеш заполняете блоками по 16 байт. А из кеша в память льется струей.

N>PS Кстати, может кто сказать почему в SSE 16 максимум (?)? Почему не больше?


Потому что самые большие програмно доступные регистры у x86 — это 16-байтные регистры SSE

N>И, пардон, что такое "TC"?


Topic Starter, вестимо
Re[4]: Быстрый способ обнулить блок памяти?
От: Pavel Dvorkin Россия  
Дата: 10.09.11 12:28
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Это от компилятора зависит. gcc инлайнит эти функции, если оптимизация включена. Насчет MSVC я не особенно копенгаген . Смотрите здесь: http://msdn.microsoft.com/en-us/library/26td21ds.aspx


Черт его знает. /Oi установил, Release, но все равно call и jmp в адреса 0x7xxxxxxx. Может, что-то не так делаю. А впрочем, ты прав — на миллион байт это все копейки.
With best regards
Pavel Dvorkin
Re[5]: Быстрый способ обнулить блок памяти?
От: nbie  
Дата: 10.09.11 12:38
Оценка:
Коллеги, все понял, кроме этого:

N> Если заполнение блоками по 16 байт — это максимум скорости, то проделать это самому в цикле разве не будет оптимальным?

P> Это вы кеш заполняете блоками по 16 байт. А из кеша в память льется струей.

Поясните еще раз эту мысль ("А из кеша в память льется струей" — к чему это).
Я, конечно пойду читать про кеш, но я думал я заполняю память по указателю непосредственно.
Re[6]: Быстрый способ обнулить блок памяти?
От: Pzz Россия https://github.com/alexpevzner
Дата: 10.09.11 12:44
Оценка: 8 (4)
Здравствуйте, nbie, Вы писали:

N>Поясните еще раз эту мысль ("А из кеша в память льется струей" — к чему это).

N>Я, конечно пойду читать про кеш, но я думал я заполняю память по указателю непосредственно.

Вы пишете в кеш. Это такая маленькая быстрая память, припаянная прямо к процессору. Процессор потом, по своему усмотрению и без вашего участия, перемещает данные из кеша в память — да еще и с промежуточным буферированием в контроллере памяти.

Из кеша в контроллер памяти данные уходят блоками размером с cache line (это минимальная единица обмена между кешом и системной памятью). У современных x86-х процессоров кеш-лайн имеет размер 64 байта. Контроллер же памяти старается склеить эти обращения так, чтобы набрать целую "строку": работа "строками" — это самый быстрый способ работы с памятью. Чему сейчас равна строка, я даже и не знаю.

В общем, все сложно
Re: Быстрый способ обнулить блок памяти?
От: MasterZiv СССР  
Дата: 10.09.11 17:16
Оценка:
On 10.09.2011 13:08, nbie wrote:
memset
Posted via RSDN NNTP Server 2.1 beta
Re: Быстрый способ обнулить блок памяти?
От: rm822 Россия  
Дата: 11.09.11 00:09
Оценка: 2 (1) +1
Здравствуйте, nbie, Вы писали:

N>Добрый день, коллеги.

N>Подскажите самый быстрый способ обнулить блок памяти (1000000 байт)?
самый бйстрый способ его просто выкинуть и выделить новый через virtualalloc
там он гарантированно будет забит нулями и занимается этим system idle process
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re: Быстрый способ обнулить блок памяти?
От: buver  
Дата: 11.09.11 20:01
Оценка:
N>Добрый день, коллеги.
N>Подскажите самый быстрый способ обнулить блок памяти (1000000 байт)?

N>PS Кроме SSE инструкций (заполнять по 16 байт) ничего нет?


вот тут есть какие-то слова по этому поводу
http://lwn.net/Articles/255364/
общая идея в том, что кеш использовать в этом случае не надо — это дополнительные затраты на чтение кешлайна, модификацию и запись назад.

кстат про sse, если у gcc задать уровень оптимизации -O3, то он даже для

for(i = 0; i<много; i++)
   buffer[i] = 0;


будет использовать sse инструкции, и я думаю в этих вопросах можно положиться на libc и gcc, ну или их виндовые аналоги.
Re: Быстрый способ обнулить блок памяти?
От: DorfDepp  
Дата: 11.09.11 20:36
Оценка: :)
Здравствуйте, nbie, Вы писали:

N>Добрый день, коллеги.

N>Подскажите самый быстрый способ обнулить блок памяти (1000000 байт)?

N>PS Кроме SSE инструкций (заполнять по 16 байт) ничего нет?


В микроволновку на 2-3 секунды. Обнулится по первому классу.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.