Re[2]: fast strncpy
От: Сергей Мухин Россия  
Дата: 19.01.08 14:24
Оценка:
Здравствуйте, remark, Вы писали:

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


S>>Интересуют предложения по оптимизации.



R>Оптимизация таких вещей — это всегда платформенно-зависимая вещь.

R>Во-первых, тебе надо определиться, для чего ты хочешь применять эту функцию. Варианты: для копирования маленьких областей, для копирования очень больших областей, для всего подряд.
R>Например для копирования очень больших областей на x86 тебе надо применять non-temporal сохранения + non-temporal предвыборку в L1$ + барьер на запись. Смотри описание и гугли по инструкциям MOVNTQ, PREFETCHNTA, SFENCE.

А потом, когда все сделаешь, надо замерить время выполнения приложения, и увидеть что твоя ф-ия копирования занимает меньше 1% времени. и выкинуть ее.
---
С уважением,
Сергей Мухин
Re[3]: fast strncpy
От: remark Россия http://www.1024cores.net/
Дата: 19.01.08 15:02
Оценка: +1
Здравствуйте, Сергей Мухин, Вы писали:

СМ>Здравствуйте, remark, Вы писали:


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


S>>>Интересуют предложения по оптимизации.



R>>Оптимизация таких вещей — это всегда платформенно-зависимая вещь.

R>>Во-первых, тебе надо определиться, для чего ты хочешь применять эту функцию. Варианты: для копирования маленьких областей, для копирования очень больших областей, для всего подряд.
R>>Например для копирования очень больших областей на x86 тебе надо применять non-temporal сохранения + non-temporal предвыборку в L1$ + барьер на запись. Смотри описание и гугли по инструкциям MOVNTQ, PREFETCHNTA, SFENCE.

СМ>А потом, когда все сделаешь, надо замерить время выполнения приложения, и увидеть что твоя ф-ия копирования занимает меньше 1% времени. и выкинуть ее.



Дополнение Харриса
Автор: remark
Дата: 06.08.07

Третье правило Гуэста
Автор: remark
Дата: 07.08.07




1024cores — all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[2]: fast strncpy
От: sokel Россия  
Дата: 23.01.08 08:32
Оценка:
Здравствуйте, netch80, Вы писали:

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


S>>Предлагаю на растерзание функцию копирования строк, аналог strncpy, без недостатков оной. Не заполняет остаток нулями, всегда в конце вставляет 0. На входе принимает размер буфера назначения, на выходе дает число скопированных символов. Интересуют предложения по оптимизации.


N>Прокомментирую не только по оптимизации


N>Во-первых, интерфейс strncpy() действительно немного неадекватен обычному использованию — дело в том, что эта функция была придумана в Unix именно для заполнения полей фиксированного размера так, чтобы они потом были пригодны для memcmp (а не с ограничением по размеру), поэтому там доливание нулями. Поэтому все тесты, в которых размер приёмника больше размера источника, заведомо неадекватны; сравнивать надо не с классической strncpy(), а с, лучше всего, strcpy_s() или strncpy_s() (ISO drafts, из платформ — последние MSVC). Если же смотреть на приведённые дальше сравнения скоростей, Ваша strncpy заметно проигрывает штатной memcpy(), а это показывает, что таки старания на Си не дают достаточного результата, и ассемблер тут таки прогрессивнее. (Разумеется, если надо так делать. Я не премину повторить, что NUL-terminated strings — зло, и от них надо избавляться при любой возможности.)


не имеет смысла сравнивать strncpy не должна заменять memcpy, а то что memcpy быстрей, это и ежу понятно, фиксированный размер копируемой области, отсутствие проверки на 0.

N>Во-вторых, если strlen(src)>=dst_size, я бы делал не так — буфер заполняется полностью, \0 в него не дописывается, а возвращается dst_size. (Кстати, оригинальная strncpy делает именно так.) Это позволяет немедленно проверять на переполнение; у Вас же не отличить переполнения от полного заполнения буфера. Если кому нужна в таком случае урезанная строка, он может и вручную дописать \0 в конец буфера.


Проверить на переполнение просто — достаточно сравнить с нулем источник, по возвращенному смещению. А если такая проверка не нужна, то надо постоянно дописывать 0, то есть писать в конец буфера, который может быть довольно большим, опять таки cache latency.
Re[2]: fast strncpy
От: sokel Россия  
Дата: 23.01.08 08:41
Оценка:
Здравствуйте, remark, Вы писали:

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


S>>Интересуют предложения по оптимизации.



R>Оптимизация таких вещей — это всегда платформенно-зависимая вещь.

R>Во-первых, тебе надо определиться, для чего ты хочешь применять эту функцию. Варианты: для копирования маленьких областей, для копирования очень больших областей, для всего подряд.
R>Например для копирования очень больших областей на x86 тебе надо применять non-temporal сохранения + non-temporal предвыборку в L1$ + барьер на запись. Смотри описание и гугли по инструкциям MOVNTQ, PREFETCHNTA, SFENCE.
R>Во-вторых, погляди, не можешь ли ты наложить какие-то дополнительные ограничения на входные данные.
R>Например ты можешь потребовать, что бы обе области были выровнены на 16 байт + размер памяти под области тоже кратен 16 байтам. Тогда ты можешь не обрабатывать отдельным образом начало и конец области, а сразу и до конца шпарить по 16 байт. Я думаю, это должно дать выигрыш для маленьких областей, т.к. функция будет маленькой и простой и без дополнительных ветвлений.
R>Если же ты хочешь функцию портируемую, для всех размеров областей и без дополнительных ограничений на входные данные, то тут и никакого простора для оптимизаций нет. Остаётся только оставить функцию как есть и надеяться на оптимизатор компилятора. Но тут ты скорее всего всегда будешь отставать от библиотечной memcpy() и от intrinsic'а компилятора.

R>


Нужна была именно портируемая функция для любых размеров. Оптимизация интересна в плане С. memcpy конечно быстрей, но тут речь всё таки о строках, memcpy на 0 не проверяет. А вот дополнительные реализации, не требующие проверки на выравнивание источника и/или назначения — хорошая мысль.
Re[3]: fast strncpy
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 23.01.08 10:42
Оценка:
Здравствуйте, sokel, Вы писали:

N>>Во-вторых, если strlen(src)>=dst_size, я бы делал не так — буфер заполняется полностью, \0 в него не дописывается, а возвращается dst_size. (Кстати, оригинальная strncpy делает именно так.) Это позволяет немедленно проверять на переполнение; у Вас же не отличить переполнения от полного заполнения буфера. Если кому нужна в таком случае урезанная строка, он может и вручную дописать \0 в конец буфера.

S>Проверить на переполнение просто — достаточно сравнить с нулем источник, по возвращенному смещению.

Это значительно более громоздко писать, чем проверку вида if(strlcpy(dst,src,size)>=size){типа всё плохо;}

S> А если такая проверка не нужна, то надо постоянно дописывать 0, то есть писать в конец буфера, который может быть довольно большим, опять таки cache latency.


"Если такая проверка не нужна" — случай, когда надо просто усечь строку без всяких других последствий — крайне редок. Даже если пишешь отладочный лог (а я с ходу что-то не найду другое применение такому усечению), надо как-то указать, что строка закончилась раньше, чем допустимое место в записи в логе. А вот нормальная проверка — нужна постоянно.
The God is real, unless declared integer.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.