LINUX.ORG.RU

Ремейк coreutils. Производительность VS традиции.

 , , , ,


0

2

Прочитал я статью про /bin/true и кучу ее версий. Потом подумал посмотреть, что да как в моем Debian:

root@server:~# /bin/true --version
true (GNU coreutils) 8.5
Copyright (C) 2010 Free Software Foundation, Inc.
Лицензия GPLv3+: GNU GPL версии 3 или новее <http://gnu.org/licenses/gpl.html>
Это свободное ПО: вы можете продавать и распространять его.
Нет НИКАКИХ ГАРАНТИЙ до степени, разрешённой законом.

Автор программы — Jim Meyering.


Суть даже не в том, на кой черт столько версий. Суть в том, что если программу переписывали кучу раз и она, ничего не делая, весит 20 (!) килобайт, то что-то здесь не так.
В общем, я переписал (какое громкое слово) ее на nasm и собрал. Объем уменьшился в ~40 раз. А потом - самое веселое, тестирование производительности.
Для этого использовался следующий скрипт:

#!/bin/bash
i=0
date
until [ $i -eq 220000 ]
do
/bin/true
  i=$[$i+1]
done
date


После этого в скрипте /bin/true меняется на ./true и тест повторяется.
Тест проводился на Debian Stable x64, Xeon E3-1235 Sandy Brige, 16gb RAM DDR3 1333.

Результаты:
/bin/true - 61 sec
./true - 32 sec

C /bin/false все примерно так же. Еще сравнивал с true из busybox на нетбуке с slitaz. Ее nasm-версия обгоняет не в 2, а примерно, в полтора раза.


Я даже не знаю, что мне спросить. Зачем в ЭТИХ программах Си? Почему они такие медленные? Почему даже busybox, который призван работать на встраиваемых и маломощных железяках не использовал такой подход? Я понимаю, что vi на nasm или gas переписать - мрак и ужас. Но cat, mount, ls, true, false и еще многие - вполне возможно. И даже я бы мог это сделать, если бы захотел. Другой вопрос в том, что системное программирование в Linux прибито гвоздями к сишечке. Неужели от нее не откажутся даже ради прироста производительности?
Даже двойного?



Последнее исправление: horonitel (всего исправлений: 1)

Ща вам скажут, что кроме x86 есть куча других архитектур и надо обязательно их поддерживать, иначе не комильфо.

yirk
()

Я познаю мир (ц). Ты, видимо, ещё не слышал про питон с сишарпом.

anonymous
()

И много у тебя было реальных случаев где узким местом были cat или ls?

encyrtid
()

Я даже не знаю, что мне спросить.

спроси себя, на кой нужно крутить true в цикле 220 000 раз

dt1
()
Ответ на: комментарий от GotF

Я тестил на AMD64. Касательно других - чем плох GAS? Я использовал nasm для примера, а GAS вроде как кучу архитектур поддерживает.

horonitel
() автор топика
Ответ на: комментарий от horonitel

Нет, он родной, из репозиториев.

Тогда сравнения некорректны. Собери его для своего компа со всеми оптимизациями и сравни результаты.

Zodd
()
Ответ на: комментарий от dt1

Разумеется, зачем париться из-за 20кб места и полуминутной задержки, ведь сейчас у нас всех чудесные компьютеры, которые этого всего не заметят. Представь, что ты производитель маленькой железки и думаешь, выбрать linux + busybox или заказать себе проприетарщину. Выясняется, что хваленый линукс с утилитами не влезает в память и работает не очень-то быстро. Итог: заказ проприетарной пришивке, рост цены на девайс, одним linux-девайсом меньше.

horonitel
() автор топика
Ответ на: комментарий от horonitel

производителю маленькой железки нужно крутить true в цикле 220 000 раз?

тут написали уже, что надо узкие места искать, а не оптимизировать все подряд

dt1
()

1) В шеллах true обычно является builtin'ом, и вызов true не вызывает /bin/true

2) /bin/true еще умеет выводить документацию, да еще и на разных языках.

dmitry_vk
()
Ответ на: комментарий от Sholy

Да пожалуйста :)

«Код» это громко сказано.

bits 64 
SECTION .text
global _start           ; точка входа
_start:
        mov eax, 1      ; '_exit' syscall
        mov ebx, 0      ; хороший exit code
        int 0x80        ; ау ядро
horonitel
() автор топика
Ответ на: комментарий от dmitry_vk

1) Не везде, однако. 2) Документация в смысле --version? На встраиваемом железе суперактуально.
true - do nothing, successfully
Это все, что она должна делать.

horonitel
() автор топика
derlaft@odd:~/true$ time ./test.sh /bin/true #тру, лежащий в /bin

real    0m53.427s
user    0m16.713s
sys     0m6.084s
derlaft@odd:~/true$ time ./test.sh true #true, встроенный в шелл

real    0m1.342s
user    0m1.272s
sys     0m0.056s
derlaft@odd:~/true$ cat test.sh  #файл теста
#!/bin/bash
i=0
until [ $i -eq 50000 ]                 
do
$1
  i=$[$i+1]                                                
done

К сожалению, твой true у меня не собрался, так что сравнить не могу

derlafff
()
Ответ на: комментарий от horonitel

На встраиваемом железе суперактуально.

Стандарты есть стандарты. Всё равно, те, кому актуальна скорость выполнения этого true, внешние бинарники для этого не используют

derlafff
()

весит 20 (!) килобайт

Объем уменьшился в ~40 раз.

format ELF executable

mov eax, 1
xor ebx, ebx
int 0x80
$ fasm true.asm true
flat assembler  version 1.70.02  (16384 kilobytes memory)
1 passes, 93 bytes.
damnemall
()
Ответ на: комментарий от dt1

Нет. Только у него на этой железке будет не Xeon, как у меня на сервере. Я такое количество итераций задал именно из-за мощи процессора, чтобы результат был наглядным. И да, разница в объеме бинарника в 40 раз это тоже актуально для такой железки. Меньше памяти под прошивку = меньше цена.

horonitel
() автор топика
Ответ на: комментарий от ananas

О ней тут речи не идет, разумеется, будет куда быстрее. Все прицепились к конкретным примерам, а я говорю о том, что таким образом можно, гипотетически сделать coreutils вдвое быстрее и в 40 раз меньше. И я не вижу, что в этом плохого.

horonitel
() автор топика
Ответ на: комментарий от horonitel

Такой метод оптимизации практически применим только к простейшим программам из coreutils. Даже cat достаточно сложен, чтобы его можно было переписать на ассемблере. При этом сопровождение и портирование усложняются в разы.

dmitry_vk
()
> time /bin/true 
/bin/true  0.00s user 0.00s system 0% cpu 0.002 total

gentoo x86_64, core i3 m380

anonymous
()

кстати, был проект linux-assembly, где всё подряд переписывали на ассемблере. У них даже свой init был. Только загнулись они, ибо ассемблер тут нахер не нужен.

anonymous
()

У меня другой вопрос: Зачем в таких утилитах как true/false поддержка локалей и NLS? Ваши coreutils, glibc и прочий креп уже так и просятся, чтобы в них пихнули побольше динамита и после взрыва жыр прям разметало по прилегающей территории. Задолбало.

anonymous
()

Когда я был молодой...

...трава была зеленее, небо голубее, а глазенки излучали энтузиазм в инфракрасном диапазоне, я тоже хотел все и вся соптимизировать. А потом я вырос и воочию убедился в том, что 90% тормозов приходятся на 10% быдлокода. Так вот, дорогой друг, ты ткнул пальцев мимо этих самых 10%.

red_eyed_peguin
()
Ответ на: комментарий от anonymous

Зачем в таких утилитах как true/false поддержка локалей и NLS?

для встроенного хелпа же, ну

dt1
()
Ответ на: комментарий от horonitel

Что именно? Производительность?

Производительность в ущерб простоте, портируемости и функциональности. И ядро было сначала на ассемблере - угадай, зачем его переписали на си (потеряв ~20% скорости).

Последний релиз был 6 лет назад.

Вот и подтверждение, что это оказалось не нужно.

unsigned
()

20 (!) килобайт,

первый раз соврал, потому как:

ls -l /bin/true

-rwxr-xr-x 1 root root 4704 Apr 11 18:47 /bin/true

В общем, я переписал (какое громкое слово) ее на nasm и собрал. Объем уменьшился в ~40 раз.

Т.е. 512 байт? Да ты мастер!

4 асм-инструкции и «всего» 512 байт:)

А потом - самое веселое, тестирование производительности.

Да ты клоун!

anonymous
()

Было бы еще полезно услышать о применении /bin/true в девайсах, где критичны 20 Кб памяти. Для чего применяется? Почему для его использования нет альтернатив?

trex6
()

Зачем в ЭТИХ программах Си?

KISS же! Все равно от /bin/true производительность особая не требуется.

Eddy_Em
()
Ответ на: комментарий от anonymous

4 асм-инструкции и «всего» 512 байт:)

+100500

Используя системные динамические библиотеки, народ в 1кБ умудряется OpenGL'ную графику запихать. А тут - всего-то возвращение 0.

Eddy_Em
()

Мама дорогая!

У нее еще и man-страница есть! Мде...

Eddy_Em
()

Кстати, не надо тут про 20кБ:

cat > 1.c
main(){return 0;}

gcc 1.c 

ls -l ./a.out 
-rwxr-xr-x 1 eddy eddy 6571 мая   31 17:25 ./a.out*

Eddy_Em
()

Молодец, а теперь иди перепиши на асме тот же баш.

PolarFox
()

Ну и да, производителю встраиваемой железки твой асмовый корутилс ни во что не упёрся хотя бы потому, что он просто не запустится на ней.

PolarFox
()

Но cat, mount, ls, true, false и еще многие

да сколько же вас блин, писателей :) и не один не удосужился почитать документацию. В треде уже штук 5 вариантов «true» одинаково далёких от спецификации. И делать на asm`е аналог cat - вовсе не один день жестоко потерянного времени.

MKuznetsov 👍👍👍
()
Ответ на: комментарий от MKuznetsov

вовсе не один день жестоко потерянного времени

линупсоидам не привыкать

anonymous
()
Ответ на: комментарий от Eddy_Em

у форматов исполняемых файлов, типа ELF например, есть всякие требования к выравниванию, минимальные размеры секций, служебная информация. Так что 512 байт это нормально

Harald
()
Ответ на: комментарий от MKuznetsov

одинаково далёких от спецификации

В мане четко написано: русским по-черному:

Exit with a status code indicating success.

Т.е. это - обычная

main(){return 0;}

Eddy_Em
()
Ответ на: комментарий от Eddy_Em

В мане четко написано

а теперь читаем ещё раз и максимально внимательно :) есть условия при которых /bin/true возвращает ненулевой статус.

MKuznetsov 👍👍👍
()
Ответ на: комментарий от MKuznetsov

Не бывает такого:

DESCRIPTION
       Exit with a status code indicating success.

       --help display this help and exit

       --version
              output version information and exit

       NOTE:  your  shell  may  have its own version of true, which usually supersedes the version described here.  Please refer to your shell's documentation for
       details about the options it supports.

Eddy_Em
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.