LINUX.ORG.RU

Вышел KolibriN 8.1

 , ,


4

4

Многие уже слышали про Колибри — операционную систему написанную на ассемблере и умещающуюся на одну дискету. И это с целой кучей софта в комплекте! Завораживает? Возможно, но наши дети уже не знают зачем эти черные квадратики, да и Колибри давно уже выросла из дискеты размером 1.44 Мб — это и послужило причиной появления KolibriN Upgrade Pack, который призван собрать воедино все разбросанные по свету программы и наработки для KolibriOS.

Что сделано:

  • добавлены тени и полупрозрачность;
  • красивые обои и скины, которые можно легко менять через контекстное меню рабочего стола;
  • в поставку входят игры, среди которых Doom, Loderunner, Pig, Jumpbump и эмуляторы игровых консолей NES, SNES, Gameboy;
  • эмуляторы DosBox и ZX Spectrum позволят запустить сотни старых приложений и игр;
  • просмотрщик изображений zSea, графический редактор GrafX2, почтовый агент Liza, просмотрщик документов формата PDF, видеоплеер FPlay и многие другие программы.

Более того, вам не нужно прописывать ассоциации для этих программ в файловых менеджерах вручную — установщик сделает это сам.

>>> Скриншоты на официальном сайте

>>> Ссылка на закачку

>>> Подробности



Проверено: post-factum ()
Последнее исправление: Klymedy (всего исправлений: 8)
Ответ на: комментарий от dmfd

Он утверждал, что бэкэнды современных компиляторов генерируют более оптимальный код, чем человек. Я склонен этому верить.

Если компиляторы создал человек, то и код компилируемый им никогда не сможет быть быстрее кода написанного тем же человеком :)

Это ж логично!

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

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

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

Если компиляторы создал человек, то и код компилируемый им
никогда не сможет быть быстрее кода написанного тем же
человеком :)

Чушь. Компилятор сидит, и уныло применяет сотни алгоритмов оптимизации на всех этапах компиляции. Человек никогда так делать не будет. Напротив, он уменьшит оптимизацию по скорости в угоду читаемости и логичности кода, а компилятор на это клал.

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

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

Компьютеры делают быстрей. И делают те задания, которые недостойны человеческого интелекта.

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

Чушь. Компилятор сидит, и уныло применяет сотни алгоритмов оптимизации на всех этапах компиляции. Человек никогда так делать не будет. Напротив, он уменьшит оптимизацию по скорости в угоду читаемости и логичности кода, а компилятор на это клал.

Если мы оперируем словами «никогда» и «всегда», то значит речь идет о теории. А в теории человек тоже может перепробовать все алгоритмы.

Но скорее всего, придумает новый подход, который будет еще быстрей.

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

Но скорее всего, придумает новый подход, который будет еще быстрей.

Конкретный пример нового подхода в студию.

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

И делают те задания, которые недостойны человеческого интелекта.

А задача микроуровневой оптимизации достойна?

namezys ★★★★
()
Ответ на: комментарий от dmfd

Программирование на асме в 99% случаев — именно такое занятие.

Если программист бездарный, неопытный и не прочитал внимательно документацию процессоров, то да :)

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

Конкретный пример нового подхода в студию.

Ну классика жанра - это сортировка. Можно заоптимизироваться до чертика с всплывающими пузырьками, а можно сделать по-другому, быстрей :)

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

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

Путь ассемблерщика.

а можно сделать по-другому, быстрей

А при чём здесь ассемблер?

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

А задача микроуровневой оптимизации достойна?

Человек должен делать только то, что не может сделать компьютер. Профессиональный подход следующий:
1. Написание кода на высокоуровневом языке
2. Компиляция с полной оптимизацией
3. Выявление горлышка бутылки в критических местах
4. Поиск более оптимального алгоритма.
4.1. Если есть, то в Пункт 1.
5. Дизассемблирование скомпилированного кода, поиск возможности оптимизации на микроуровне.
6. Замена этого отрезка в высокоуровневом языке вствакой на ассемблере.

Тогда всё будет быстро и в создании и в исполнении программы.

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

А при чём здесь ассемблер?

Ассемблер при том, что человек всегда умнее компилятора.

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

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

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

Если программист бездарный, неопытный и не прочитал внимательно документацию процессоров, то да :)

Программисты, который под каждый процессор пишет заново код? Это кто?

namezys ★★★★
()
Ответ на: комментарий от acukac

Кто бы с этим спорил. Но куда лучше подтюнить язык, если таких мест «много», или сделать 1-2 вставки. Но не как не весь код и не всю логику.

namezys ★★★★
()
Ответ на: комментарий от acukac

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

Вот вы мне объясните, почему человек с этой задачей справится лучше

namezys ★★★★
()
Ответ на: комментарий от acukac

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

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

Проблески разума появились. Уверяю, в достаточно сложной программе, состоящей более чем из одного алгоритма, эта схема до пункта 5 никогда не доходит.

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

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

Ассемблерщики же. Зачем им флаги компилятора знать? Он им не нужен же.

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

Надо ему ссылочку дать хотя бы вот на это. Пусть потрясет там своими ассемблерами, авось и выйдет чего.

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

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

Я не о написании программ, а об оптимизации кода. Компилятор сможет лишь оптимировать существующий алгоритм, но т.к. он не видит дальше края тарелки и обрабатывает блоками определенного размера, не видя общей картины, то замена человек всегда будет умнее его и найдет больше возможностей.

Чем-то напоминает сжатие ZIP в зависимости от размера словаря.

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

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

Я не о написании программ, а об оптимизации кода. Компилятор сможет лишь оптимировать/компилировать существующий алгоритм в определенных рамках и т.к. он не видит дальше края тарелки, не видит цели всего этого действия и обрабатывает блоками определенного размера, не видя общей картины, то самый лучшеий человек всегда будет умнее самого лучшего компилятора и найдет больше возможностей.

Чем-то напоминает сжатие ZIP в зависимости от размера словаря.

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

Проблески разума появились. Уверяю, в достаточно сложной программе, состоящей более чем из одного алгоритма, эта схема до пункта 5 никогда не доходит.

Пункт 5 делают те, кто это умеют. У других до этого не доходит, согласен :)

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

У компилятора та же проблема и у него нет возможности провести бенчмарк в отличии от человека :)

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

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

Ну даже, например, передача параметров в процедуру через регистры, а не через стек! Это 6 тактов минимум, вместо одного :)

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

Да, а что же по вашему делает компилятор?

Переводит с одного языка на другой

namezys ★★★★
()
Ответ на: комментарий от acukac

Ну даже, например, передача параметров в процедуру через регистры, а не через стек!

Ладно бы вы про SIMD начали рассказывать. Но это-то компиляторы умеют уже сто лет. man register, man inline

У компилятора та же проблема

Нет у него этой проблемы. man compiler frontend/backend

у него нет возможности провести бенчмарк в отличии от человека

И при чём здесь ассемблер? Time profiling я могу и для скомпилированного кода провести.

Я не о написании программ, а об оптимизации кода. Компилятор сможет лишь оптимировать/компилировать существующий алгоритм в определенных рамках и т.к. он не видит дальше края тарелки, не видит цели всего этого действия и обрабатывает блоками определенного размера, не видя общей картины, то самый лучшеий человек всегда будет умнее самого лучшего компилятора и найдет больше возможностей.

Конкретных примеров так и нет? Я знал, с кем имею дело.

Пункт 5 делают те, кто это умеют.

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

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

Ну даже, например, передача параметров в процедуру через регистры, а не через стек!

Ладно бы вы про SIMD начали рассказывать. Но это-то компиляторы умеют уже сто лет. man register, man inline

И они до сих пор делают это хреново! И сам программист не имеет возможности отследить использование отдельных регистров! А значит и не знает какой из них можно использовать. А пушить перед этим в стек другие переменные - тоже тупо!

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

inline то зачем придумали? А вы всегда знаете, что данный вызов не воспользуется другими регистрами? где гарантия?

А вот компилятору можно было бы объяснить, чтоб он это проверял

namezys ★★★★
()
Ответ на: комментарий от SZT

Не, ну если им так хочется, то calling conversion и нарушить можно, только обучить этому компилятор надо.... Но тут есть больша ясложность

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

inline то зачем придумали? А вы всегда знаете, что данный вызов не воспользуется другими регистрами? где гарантия?

А вот компилятору можно было бы объяснить, чтоб он это проверял

А где гарантия, что вы напишите программу ХеллоуВорлд, которая будет работать? Вот тут примерно такая же гарантия :)))

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

гарантий куда больше. по крайней мере происходит очень много проверок. а у вас нет.

Но при вашем желании можно было научить компилятор делать то, что вам надо. И это было бы эффективней

namezys ★★★★
()
Ответ на: комментарий от acukac

Это 6 тактов минимум, вместо одного

#include <stdio.h>

int main() {
        int count = 1000000;
        int t1, t2, t3, t4;
        asm volatile(
                "mov %[count], %%ecx\n\t"
                "rdtsc\n\t"
                "mov %%eax, %%ebx\n\t"
                "1: push %%eax\n\t"
                "pop %%eax\n\t"
                "dec %%ecx\n\t"
                "test %%ecx, %%ecx\n\t"
                "jnz 1b\n\t"
                "rdtsc\n\t"
                "mov %%ebx, %[t1]\n\t"
                "mov %%eax, %[t2]\n\t"
                : [t1]"=r"(t1), [t2]"=r"(t2)
                : [count] "r" (count)
                : "eax", "ebx", "ecx", "edx"
        );

        asm volatile(
                "mov %[count], %%ecx\n\t"
                "rdtsc\n\t"
                "mov %%eax, %%ebx\n\t"
                "1: mov %%ecx, %%edx\n\t"
                "mov %%edx, %%ecx\n\t"
                "dec %%ecx\n\t"
                "test %%ecx, %%ecx\n\t"
                "jnz 1b\n\t"
                "rdtsc\n\t"
                "mov %%ebx, %[t1]\n\t"
                "mov %%eax, %[t2]\n\t"
                : [t1]"=r"(t3), [t2]"=r"(t4)
                : [count] "r" (count)
                : "eax", "ebx", "ecx", "edx"
        );

        printf("delta1: %d\n", t2 - t1);
        printf("delta2: %d\n", t4 - t3);
}
[~]$ ./test2
delta1: 3844133
delta2: 3005741
[~]$ ./test2
delta1: 4008326
delta2: 3134324
[~]$ ./test2
delta1: 3844955
delta2: 3005703

чото не видно разницы в 6 раз. Может назовете методику измерения?

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

1. Почитайте, что происходит при push и pop. Сколько регистров при этом изменяется.

2. «dec %%ecx\n\t»
«test %%ecx, %%ecx\n\t»
«jnz 1b\n\t»

является весьма крупным оверхедом теста, что уже приводит к другой пропорции прироста скорости.

Пример:
50(тест)+50(оверхед)=100
10(тест)+50(оверхед)=60

Тест исполнялся в пять раз быстрей, но прирост меньше, чем в два раза из-за константного оверхеда.

3. push и pop записывают/читают RAM, а это однозначно в сотни раз медленней, даже если это кэш процессора.

4. Плюс к тому, параллелизация на уровне процессора push и pop невозможна, ни при выполнении одного потока инструкций в одном ядре, ни двух потоков инструкций в разных ядрах т.к. общие указатели на стек и оба потока обращаются к RAM.

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

кстати, лучше уж брать rdtscP - иначе вообще хрен поймешь, что там творится :)

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

Я так понял, вы вообще не в курсах ассемблера.

А по моему вы даже близко не читали о компиляторах. Книжку дракона хоть осилили?

namezys ★★★★
()
Ответ на: комментарий от acukac

3. push и pop записывают/читают RAM, а это однозначно в сотни раз медленней, даже если это кэш процессора.

Я и рассчитывал на то, что будет заметная разница, а получилось что оверхед сравним с jmp.

4. Плюс к тому, параллелизация на уровне процессора push и pop невозможна, ни при выполнении одного потока инструкций в одном ядре, ни двух потоков инструкций в разных ядрах т.к. общие указатели на стек и оба потока обращаются к RAM.

Почему нет? У каждой нити свой стек обычно. Не представляю, зачем могут понадобиться нити на общем стеке.

AptGet ★★★
()
Ответ на: комментарий от acukac
#include <stdio.h>
#include <sched.h>
#include <sys/mman.h>

int main() {
        int count = 5000000;
        int val;
        int t1, t2, t3, t4;

        struct sched_param param;
        param.sched_priority = sched_get_priority_max(SCHED_FIFO);
        if (sched_setscheduler(0, SCHED_FIFO, &param))
                perror("sched_setscheduler");


        if (mlockall(MCL_CURRENT))
                perror("mlockall");

        asm volatile(
                "mov %[count], %%esi\n\t"
                "rdtscp\n\t"
                "mov %%eax, %%ebx\n\t"
                ".p2align 4\n\t"
                "1: mov %%eax, %[val]\n\t"
                "mov %[val], %%eax\n\t"
                "dec %%esi\n\t"
                "test %%esi, %%esi\n\t"
                "jnz 1b\n\t"
                "rdtscp\n\t"
                "mov %%ebx, %[t1]\n\t"
                "mov %%eax, %[t2]\n\t"
                : [t1]"=g"(t1), [t2]"=g"(t2), [val]"+m"(val)
                : [count] "g" (count)
                : "eax", "ebx", "ecx", "edx", "esi", "memory"
        );

        asm volatile(
                "mov %[count], %%esi\n\t"
                "rdtscp\n\t"
                "mov %%eax, %%ebx\n\t"
                ".p2align 4\n\t"
                "1: mov %%ecx, %%edx\n\t"
                "mov %%edx, %%ecx\n\t"
                "dec %%esi\n\t"
                "test %%esi, %%esi\n\t"
                "jnz 1b\n\t"
                "rdtscp\n\t"
                "mov %%ebx, %[t1]\n\t"
                "mov %%eax, %[t2]\n\t"
                : [t1]"=g"(t3), [t2]"=g"(t4)
                : [count] "g" (count)
                : "eax", "ebx", "ecx", "edx", "esi", "memory"
        );

        printf("delta1: %d\n", t2 - t1);
        printf("delta2: %d\n", t4 - t3);
}
[~]$ sudo ./test2
delta1: 22712278
delta2: 10141085
[~]$ sudo ./test2
delta1: 20859123
delta2: 10014537
[~]$ sudo ./test2
delta1: 19664553
delta2: 10019416

Ну что же, разница в 2 раза. Seems legit.

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

Я и рассчитывал на то, что будет заметная разница, а получилось что оверхед сравним с jmp.

Не, ну если речь идет о push и pop против mov, то это и надо измерять :)

Почему нет? У каждой нити свой стек обычно. Не представляю, зачем могут понадобиться нити на общем стеке.

Я говорил о двух случаях:

1. Одна нить, но процессор выполняет некоторые упорядоченые инструкции параллельно, если они с друг другом не конфликтуют. Т.е., например, при передачи двух параметров «mov еax,[парам1]; mov ebx,[парам2]» две инструкции выполнятся параллельно, начиная с первого Пентюха. «push [парам1], push [парам2]» параллельно выполняться не могут т.к. изменяется указатель стека в обеих операциях.

2. Параллельные нити имеют каждый свой стек, но и тот и другой стек лежат в RAM, значит получается конкурентный доступ к памяти и при pop и при push. Да к разным кускам RAM, но к одной физической.

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

Ну что же, разница в 2 раза. Seems legit.

Интересный результат был бы еще, если запустить 100 нитей одновременно :) Думаю, там разница была бы раз в десять даже на двух ядрах :)

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

Не, ну если речь идет о push и pop против mov, то это и надо измерять :)

Если обращение к памяти сравнимо по оверхеду с jmp, то можно и не измерять. Все равно при вызове функции основной оверхед будет от call.

1. Одна нить, но процессор выполняет некоторые упорядоченые инструкции параллельно, если они с друг другом не конфликтуют. Т.е., например, при передачи двух параметров «mov еax,[парам1]; mov ebx,[парам2]» две инструкции выполнятся параллельно, начиная с первого Пентюха. «push [парам1], push [парам2]» параллельно выполняться не могут т.к. изменяется указатель стека в обеих операциях.

А оно внутри никак не может оттранслироваться в

str парам1, [sp]
str парам2, [sp, #4]
add sp, sp, #8

и выполниться одновременно? Intel Architecture Optimization Reference Manual не читал.

2. Параллельные нити имеют каждый свой стек, но и тот и другой стек лежат в RAM, значит получается конкурентный доступ к памяти и при pop и при push. Да к разным кускам RAM, но к одной физической.

пока нет кэш-промахов все ok. А если есть, то никакие регистры не помогут, т.к. их мало.

AptGet ★★★
()
Ответ на: комментарий от acukac

Интересный результат был бы еще, если запустить 100 нитей одновременно :) Думаю, там разница была бы раз в десять даже на двух ядрах :)

да что интересного, там весь оверхед был бы от переключений контекста

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