LINUX.ORG.RU

Линкеры. Оптимизация и удаление лишнего кода во время линковки.

 , , , линкеры


3

3

Здравствуйте. Собственно у меня несколько вопросов по поводу работы линкеров в современных тулчейнах.
Во первых, с удивлением обнаружил, что линкер из binutils по умолчанию линкует сожержмое объектных файлов ПОЛНОСТЬЮ. То есть, даже если из одного объектного файла с несколькими функциями во всей программе используется только одна из них - всё равно прилинковано будет всё содержимое объектного файла. Что интересно, линкер от M$ под оффтопиком по умолчанию делает тоже самое.
Я знаю что для gcc и ld можно укзать специальные опции, благодяря которым компилятор каждую функцию поместит в отдельную секцию, а линкер потом вырежит все неиспользуемые. У линкера от M$ тоже есть специальная опция.


Но почему такое поведение не принято по умолчанию? Это выглядит как просто расходование дискового пространства - зачем мне в программе код, который нигде не используется? Мне такое поведение кажется глупым, потому прошу знающих людей объяснить и указать где я не прав.


Соответсвенно ещё вопрос, насколько современные линкеры стрипят код - сколько в создаваемых с помощью современных тулчейнов лишнего, совершенно не нужного кода?
Буду особенно благодарен, если кто скажет чего можно почитать в тему.


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

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

#include <stdio.h>
#include <dlfcn.h>
void v()
{
printf("unused\n");
}
int main()
{
void *s=NULL;
void (*vf)()=NULL;
if (!(s=dlopen(NULL,RTLD_NOW)))
	printf("dlerror %s\n",dlerror());
if (!(vf=dlsym(s,"v"))) 
	printf("dlerror %s\n",dlerror());
else
	(vf)();
dlclose(s);
return 0;
}

$ gcc -Wall -rdynamic -fdata-sections -ffunction-sections  test.c -ldl -Wl,--gc-sections
$ ./a.out
dlerror ./a.out: undefined symbol: v
$ gcc -Wall -rdynamic test.c -ldl
$ ./a.out
unused
$
anonymous
()
Ответ на: комментарий от Pavval

Я полазил по домашней странице. Есть чего почитать, да. Спасибо за наводку!

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

$ gcc -Wall -rdynamic -fdata-sections -ffunction-sections test.c -ldl -Wl,--gc-sections $ ./a.out dlerror ./a.out: undefined symbol: v $ gcc -Wall -rdynamic test.c -ldl $ ./a.out unused

Интересный пример. По сути из исполняемого файла была сделана динамическая библиотека. Вообще, в первом случае gcc повёл себя странно - очевидно же что с динамическими библиотеками (вообще - shared objects) такое не должно приминяться. Хотя с другой стороны что его попросили, то он и сделал.

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

arbv
() автор топика

Это выглядит как просто расходование дискового пространства - зачем мне в программе код, который нигде не используется?

У тебя есть гарантия того, что та самая функция, которую ты дёрнул из своей программы, не дёргает другую функцию из этого же объектного файла?

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

Выше (на предидущей странице) я уже говорил. В некоторых случая можно быть точно уверенным. Но даже в этих случаях лишнее не удаляется. http://www.linux.org.ru/add_comment.jsp?topic=10115944&replyto=10117477 http://www.linux.org.ru/forum/development/10115944?cid=10117994 (комментарий) и там дальше.

У тебя есть гарантия того, что та самая функция, которую ты дёрнул из своей программы, не дёргает другую функцию из этого же объектного файла?

На сколько у меня есть гарантия, я и пытаюсь выяснить.

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

Если это разделяемая библиотека, то там все функции видимы из использующих её файлов (в отличие, например, от винды), поэтому их нельзя так просто выбросить. А если это исполнимый файл без position-independent code, то нам необязательно даже раз напрямую вставлять адрес, его можно посчитать из других констант.

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

И ещё остаётся ведь вероятность, что код будет пропатчен в памяти с поиском функций по сигнатурам каким-нибудь. Это, конечно, совсем крайний случай, но, во-первых, и его надо предусмотреть, а во-вторых, какое-нибудь DRM и не такое может сотворить.

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

И ещё остаётся ведь вероятность, что код будет пропатчен в памяти с поиском функций по сигнатурам каким-нибудь.

Верно. Но он будет пропатчен уже в памяти. К линкеру то это отношения не имеет?

Случай, когда мы не можем быть точно уверены что функция не использовалась я не исключаю, даже если о ней нет упоминания в других объектных файлах. Просто очень тяжело это прредставить. Это так или иначе очень необычный случай и уж точно не распространённый.

И его нужно обмозговать получше.

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

arbv
() автор топика

что линкер из binutils по умолчанию линкует сожержмое объектных файлов ПОЛНОСТЬЮ. То есть, даже если из одного объектного файла с несколькими функциями во всей программе используется только одна из них - всё равно прилинковано будет всё содержимое объектного файла. Что интересно, линкер от M$ под оффтопиком по умолчанию делает тоже самое.

где тег «я познаю мир»?

Но почему такое поведение не принято по умолчанию? Это выглядит как просто расходование дискового пространства - зачем мне в программе код, который нигде не используется? Мне такое поведение кажется глупым

а ты возьми генту и собери...

Собрал? Молодец. А теперь собери с этой своей опцией. Когда соберёшь — возвращайся.

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

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

чисто там, где не сорят. Если программист встроил «лишний» код, то он зачем-то нужен. Может раньше был нужен, или потом будет нужен. Не важно. Линкер этого решать не может.

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

а ты возьми генту и собери...

Использование source-based дистрибутивов не делает вас лучше других. Если захочу - то соберу, можете не сомневаться. ;-)

Если программист встроил «лишний» код, то он зачем-то нужен. Может раньше был нужен, или потом будет нужен. Не важно. Линкер этого решать не может.

Лишний код *потом* может пригодиться в уже откомпилированной программе? :-) Воистину, првильно подметил i-rinat выше:

Сборка большого количества программ в полуавтоматическом режиме (source-based дистрибутивы) не даёт опыта разработки программ.

<я познаю мир> Я надеюсь, что вы ещё скажете что либо более конструктивное и полезное. Даже не знаю, кому этот тег полезнее. </я познаю мир>

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

Использование source-based дистрибутивов не делает вас лучше других. Если захочу - то соберу, можете не сомневаться

поставь в комментарий: emulek — фанатег Slackware Linux, считает пользователей всех остальных OS — несчастными дебилами.

(шучу конечно)

Лишний код *потом* может пригодиться в уже откомпилированной программе?

ну вот ситуация: ты пишешь программу, которая работает с ☣ числами. Естественно в твоей программе не все Over9000 операций с ☣ числами, а только 1800(типичный случай). Вот и подумай, сколько времени у линкера займёт разбить либу на 9000 кусков, и собрать из них сборку в 1800 кусков? Ты состаришься, пока это всё будет собираться... Т.е. программисту это не нужно и вредно. А нужно-ли это юзеру? Учитывая тот факт, что собственно код занимает <1% места, и со временем ситуация только усугубляется? Ну сэкономишь ты 100% кода(в идеале), толку-то, если программа похудеет менее, чем на 1%?

Воистину, првильно подметил i-rinat выше: Сборка большого количества программ в полуавтоматическом режиме (source-based дистрибутивы) не даёт опыта разработки программ.

это он не про меня сказал.

Я надеюсь, что вы ещё скажете что либо более конструктивное и полезное.

это зависит от ваших вопросов.

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

ну вот ситуация: ты пишешь программу, которая работает с ☣ числами. Естественно в твоей программе не все Over9000 операций ...

Вы я так понял описываете здесь как быть, если это динамическая библиотека? Чуть выше случай с динамическими библиотеками разбирали. http://www.linux.org.ru/forum/development/10115944?cid=10118855 (комментарий) Да тут всё чуть сложнее - в общем случае её так сильно не отстрипиш. На то и библиотека - там много функций, которые могут не использоваться в одной программе, но нужны в другой. Но в общем случае её саму тоже можно отстрипить - отдельно при её сборке.

Вот и подумай, сколько времени у линкера займёт разбить либу на 9000 кусков

На самом деле ничего на 9000+ кусков пилить то и не надо - внутри объектных файлов всё уже и так распилено (уже обсуждали в треде), нужно только этой инфой воспользоваться должным образом. Да это потребует чуть больше ресурсов, но такие «тёмные панорамы», где всё супер долго линкуется ИМХО рисовать не надо. Где это может быть полезно - непосредственно при сборке самих программ (да, да К. О.) и использовании статических библиотек. Допустим, у вас есть какие-то наработки, которые вы таскаете из проекта в проект (у меня есть,у всех кто программирует, они есть). Не факт что весь код из них в конкретном проекте нужен (из дюжини функций, например нужно 3). Но в самом исполняемом файле окажется код ВСЕХ функций. Это же явно лишнее. И как мне кажется от лишнего можно избавиться не очень большой ценой. Да компьютеры сейчас мощные, да «и так всё работает», да размер исполняемых файлов ни кого не волнует (демомейкеры с этим, думаю не согласны). Но, если от этого «балласта» можно избавиться не большой ценой, разве это плохо? Я пытаюсь выяснить сейчас:

  • - на сколько я имею право считать «символ» (ту же функцию) из объектного файла лишним, если к нему ни разу на прямую не обращались?
  • - почему в словременных инструментриях такая оптимизация не выполняется, при том что те же линкеры умеют и более cложные вещи (то же LTO)? Какие здесь подводные камни?

Осбоенно интерисует первый вопрос, ибо частично отвечает и на второй. Что интересно, вроде тот же Turbo C умел такое делать. На сколько правда - не знаю, не застал.

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

Осиль c99, static/(static)inline и хеадер-онли либы/запил. Твои проблемы исчезнут, а лто и линкер будет просто не нужен. Это некстген и рядовые бомжи до этого ещё не доросли. Либо юзай lto - он выкидывает ненужное по дефолту.

А так всем покласть на то что там линкует линкер - тебе же полкасть, что на раздельной конпеляцией ты получаешь нереальный оверхед по размеру кода, а уж про перфоманс я и не заикаюсь? Так же и линкеру покласть. Хочешь - укажи явно, всем лень врубать по делфту, чтобы потом пацаны ныли «апачемууменяпропалифункции?».

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

Вы я так понял описываете здесь как быть, если это динамическая библиотека?

не. ТС говорил про статическую ЕМНИП.

Но в общем случае её саму тоже можно отстрипить - отдельно при её сборке.

вопрос был не о том, можно или нельзя. Вопрос был «почему не дефолт?». Я не этот вопрос отвечал.

На самом деле ничего на 9000+ кусков пилить то и не надо - внутри объектных файлов всё уже и так распилено

распилено. Но ведь надо ещё и Over7200 рандомных кусков выкинуть. Я не говорил, что «нельзя», я говорил — долго.

где всё супер долго линкуется ИМХО рисовать не надо.

попробуй собрать FireFox на 512Мб. Соберётся он быстро(относительно), а вот линковаться он будет ВЕЧНО. У меня конечно нет проектов уровня FireFox, но хелловорлды я тоже не пишу. Т.ч. вопрос времени меня волнует.

Не факт что весь код из них в конкретном проекте нужен (из дюжини функций, например нужно 3). Но в самом исполняемом файле окажется код ВСЕХ функций. Это же явно лишнее.

ну почему «лишнее»? Зачем в каждой компиляции обмазываться вашими интеллектуальными стрипами? Которые будут жутко тормозить? Работать-то будет также. Ну почти. А из-за этого «почти» лучше и в релизе оставить.

И как мне кажется от лишнего можно избавиться не очень большой ценой.

я и избавляюсь:

#if 0
лишний код
#endif

Да компьютеры сейчас мощные, да «и так всё работает», да размер исполняемых файлов ни кого не волнует (демомейкеры с этим, думаю не согласны). Но, если от этого «балласта» можно избавиться не большой ценой, разве это плохо?

выделенное слово тоже имеет свою цену. И не малую.

- на сколько я имею право считать «символ» (ту же функцию) из объектного файла лишним, если к нему ни разу на прямую не обращались?

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

ИМХО автоматика тут неуместна. Максимум — предупредить должен линкер, дескать «такой-то символ нигде не используется», может ембеддщикам это будет полезно. Я не в курсе, мне не нужно. За всех я не буду говорить...

почему в словременных инструментриях такая оптимизация не выполняется, при том что те же линкеры умеют и более cложные вещи (то же LTO)? Какие здесь подводные камни?

ИМХО времени уходит много, а экономия «на спичках».

LTO иногда даёт ОГРОМНЫЙ профит. Ну как пример, рассмотрим метод, перегруженный как operator++(int){ auto t; x++; return t; }, ясное дело, что в for(i=0; i<I; i++) никакое t нафиг не нужно, и его можно выкинуть. Вот только компилятор этого не видит, т.к. оно в другом модуле. В итоге, вместо одной команды INC REG, компилятор пихает целую функцию из другого модуля. А это раз в 20 дольше. И никто не говорил, что этот участок не критический. И эту беду никак не исправить, увы. (ну можно использовать макросы/шаблоны и прочие говноисправления, которые фактически пихают один код в другой)

Осбоенно интерисует первый вопрос, ибо частично отвечает и на второй. Что интересно, вроде тот же Turbo C умел такое делать. На сколько правда - не знаю, не застал.

я тогда был юным и прыщавым засранцем. И точно не знаю. Знаю, что в те времена профит был значительный. В 16и битной системе код больше сегмента (64К) — это уже было проблемой, тормозами и глюками. В 32х битной можешь хоть 64Мб кода задолбить, нет проблемы.

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

Осиль c99, static/(static)inline и хеадер-онли либы/запил. Твои проблемы исчезнут

за то новые появятся. Которые решены 40 лет назад.

что на раздельной конпеляцией ты получаешь нереальный оверхед по размеру кода

мне насрать на размер /bin/false. Если она завтра будет весить на 23К, а 32К, я этого не замечу.

а уж про перфоманс я и не заикаюсь

попробуй. И подкрепи тестом: напиши программу, и собери. А мы посмотрим, что быстрее. Или признай, что ты — балабол.

всем лень врубать по делфту, чтобы потом пацаны ныли «апачемууменяпропалифункции?».

да. Лень. И да, пацаны ноют. Но самое главное — я не вижу профита, но вижу геморрой.

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

В 16и битной системе код больше сегмента (64К) — это уже было проблемой, тормозами и глюками.

Какие проблемы, какие глюки? Кто тебе это сказал? :)

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

Что интересно, вроде тот же Turbo C умел такое делать. На

сколько правда - не знаю, не застал. Нет, не умел.

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

за то новые появятся. Которые решены 40 лет назад.

Как ты тупая ссанина меня одалела. Примеры приведи.

мне насрать на размер /bin/false. Если она завтра будет весить на 23К, а 32К, я этого не замечу.

А теперь, животное, возьми /usr/bin/* /usr/lib*/* Ах да, тыж животное ничего про so и libc не знаешь - ну погугли через какую жопу вызываются libc функции, да и вообще любые shared call.

попробуй. И подкрепи тестом: напиши программу, и собери. А мы посмотрим, что быстрее. Или признай, что ты — балабол.

man qsort, животное. Ты в каждом споре со мной был обоссан в нулину, говно. Твоя неимоверная тупость меня просто одалела.

да. Лень. И да, пацаны ноют. Но самое главное — я не вижу профита, но вижу геморрой.

Ты обоссанная макака, ты тотальная обоссанная нулина, которая нихрена не знает, но кукарекать любит.

Как ничего не можущий маздайский 16битный сброд, обоссанный в говно любой макакой на лоре, скилла которого еле-еле на хелворд хватит - может вообще о чем-то кукарекать, несчти какую-то чушь про геморой. Знай своё место прошмандовка.

Иди на свой говнофорум, мне одалело тут вводить капчу и не оскарблять тебя. Там я тебя попацаночке втопчу в говно.

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

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

Эта макака не различает рантайм, ОС, хардварвный и прочие левелы. Его выхлоп состоит из предположений идиота основанных на протухшей макулатуре, тотальном отсутвии практики, мозга и вообще каких-то способней к логичному рассуждению.

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

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

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

В 16и битной системе код больше сегмента (64К) — это уже было проблемой, тормозами и глюками.

Какие проблемы, какие глюки? Кто тебе это сказал? :)

обычная команда jmp/call не в состоянии передать управление на другой сегмент. Нужно использовать специальную форму, которая меняет все 20 битов адреса. Т.ч. обычной командой можно прыгать только внутри одного сегмента. А глюки возникают потому, что в двух регистрах 32 бита, а в адресе всего 20. Т.ч. отображение ещё и не однозначно.

К счастью, эти вопросы давно неактуальны.

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

Да, это назывался far переход, для которого нужно было передать сегмент и смещение. Только никаких проблем (а тем более глюков) это никогда не вызывало. Зато давало возможность адресовать все доступные тогда 640Kb памяти.

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

А теперь, животное, возьми /usr/bin/* /usr/lib*/* Ах да, тыж животное ничего про so и libc не знаешь - ну погугли через какую жопу вызываются libc функции, да и вообще любые shared call.

мудилка:

root@amilo:~/tmp# du -shx /usr/bin/
365M	/usr/bin/
root@amilo:~/tmp# du -shx /usr/lib
1,2G	/usr/lib

У меня ОЧЕНЬ дорогая память(ибо флешка), Один гиг стоит 48 рублей 45 копеек!!! А всё ПО (начиная с говна мамонта вроде ed, и заканчивая последней коллекцией компиляторов включая ada с fortran и последней XFCE) стоит 76 (СЕМЬДЕСЯТ ШЕСТЬ) РУБЛЕЙ!

Да, ты наверное столько бабла сразу и не видел...

попробуй. И подкрепи тестом: напиши программу, и собери. А мы посмотрим, что быстрее. Или признай, что ты — балабол.

man qsort, животное. Ты в каждом споре со мной был обоссан в нулину, говно. Твоя неимоверная тупость меня просто одалела.

дебилка, где код, который доказывает твою правоту?

Иди на свой говнофорум

ты про какой?

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

а с него на слаку ... Сейчас эта макака хреначит какое-то говно на псевдоплюх под маздай на плюсах

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

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

Да, это назывался far переход, для которого нужно было передать сегмент и смещение. Только никаких проблем (а тем более глюков) это никогда не вызывало.

да, конечно. Кто тебе это сказал?

Зато давало возможность адресовать все доступные тогда 640Kb памяти.

640кб было только в MS-DOS. А вообще там было ровно 1048576 байт.

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

да, конечно. Кто тебе это сказал?

А зачем мне что говорить, когда я для него программы писал. :)

640кб было только в MS-DOS.

Так про то и речь. Или ты на Turbo C в конце восьмидесятых под 32 битный линукс писал? ;)

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

мудилка:

man l1i.

У меня ОЧЕНЬ дорогая память(ибо флешка), Один гиг стоит 48 рублей 45 копеек!!!

Причем тут память, именно по этой причине тебе и нужен ссд, чтобы у тебя не «тормазило», но ты животное не понимаешь этого - это побычный эффект shared-модели. Экономят оперативку, размер кода не из-за того, чтобы сэкономить, а чтобы не тормазило. Представляешь да?

Да и вообще, обсосок - ты читай тред - про «экнонимию места» кукарекал ТС, а не я. Мне вообще покласть сколько мой код занимает места, но он занимает его ПРАВИЛЬНО, в отличии от твоего говда, да и всего говна в /usr/lib /usr/bin

Да, ты наверное столько бабла сразу и не видел...

Зачем ты кукарекаешь про бабло, нищая макака - пукан до сих пор болит?

дебилка, где код, который доказывает твою правоту?

А ты я смотрю туповатый - qsort тебе код. Идёшь сравниваешь хеадернли релизацию(С++ stl) и shared-реализацию(C libc).

Обоссать тебя мне как 2 пальца обасфальт.

ты про какой?

http://club2.org.ru/index.php?showtopic=478

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

мудилка:

man l1i.

У меня ОЧЕНЬ дорогая память(ибо флешка), Один гиг стоит 48 рублей 45 копеек!!!

Причем тут память, именно по этой причине тебе и нужен ссд, чтобы у тебя не «тормазило», но ты животное не понимаешь этого - это побычный эффект shared-модели. Экономят оперативку, размер кода не из-за того, чтобы сэкономить, а чтобы не тормазило. Представляешь да?

Да и вообще, обсосок - ты читай тред - про «экнонимию места» кукарекал ТС, а не я. Мне вообще покласть сколько мой код занимает места, но он занимает его ПРАВИЛЬНО, в отличии от твоего говда, да и всего говна в /usr/lib /usr/bin

Да, ты наверное столько бабла сразу и не видел...

Зачем ты кукарекаешь про бабло, нищая макака - пукан до сих пор болит?

дебилка, где код, который доказывает твою правоту?

А ты я смотрю туповатый - qsort тебе код. Идёшь сравниваешь хеадернли релизацию(С++ stl) и shared-реализацию(C libc).

Обоссать тебя мне как 2 пальца обасфальт.

ты про какой?

http://club2.org.ru/index.php?showtopic=478

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

ты почти угадал. Правда маздая в планах нет.

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

Потом ты пришел на лор кукарекать о чем-то, решил стать типа илитным, а т.к. тогда было модно «патрегбог» - пошел в слаку. За лет 5 набил звёзды и стал кукарекать «маздайка не нужна». Сейчас ваяешь примтивное плюсовое(скорее деревенская сишка с классами) говно за еду.

Впрочем, мой код обычно хорошо портируем на другие системы

У тебя нет кода.

т.ч. может будет и под маздай.

Где работает мистическое говно из-подтебя меня мало волнует. Кода у тебя нет.

Следите за рекламой.

Ок, пацанчик.

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

Не знаю что это за цифры, но на той машине с процессором 8086 с которой мне приходилось иметь дело (хоть они и назывались PC, но в те времена график ее использования был расписан по часам для кучи людей), было ровно 640 Кб. :)

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

Не знаю что это за цифры

Это глитч сегментной адресации, появился на 286-х вроде бы. Адреса FFFF:xxxx, где xxxx >= 0x10 не заворачивались на начало адресного пространства, как на 8086, а указывали на вполне доступную память. Поэтому появлялось ещё почти 64 кило памяти; её ещё HMA называли.

i-rinat ★★★★★
()
Ответ на: комментарий от anonymous

А ты я смотрю туповатый - qsort тебе код. Идёшь сравниваешь хеадернли релизацию(С++ stl) и shared-реализацию(C libc).

ты проверил? Получил пруф, который меня «сливает»? Молодец. Теперь замени свой говнокод, который нихрена не делает на что-то осмысленное. Например посчитай sha-1 от значений, их сравни, и по ним сортируй. А то IRL такой говнокод, как у тебя, который сравнивает два int'а, никому даром не нужен. Хотя бы потому, что int'ы можно отсортировать за O(N), что по любому быстрее на порядки для любой реализации qsort(), хоть на голом асме.

остальное даже комментировать лень. Ты в очередной раз доказал свою, как ты говоришь, «анскильность».

emulek
()
Ответ на: комментарий от i-rinat

Ааа, ну это 80286, мы про 8086 пока говорим. :)

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

было ровно 640 Кб

это как 3Гб памяти в дешёвых ноутах. Там был cs:ip, т.е. два регистра по 16 бит. Но адрес был не 32 бита, а вычислялся(внутри CPU) как cs*16+ip. То, куда указывало ip называлось «сегментом кода», и имело размер 16 бит(65536). А вместе с cs получалось в 16 раз больше, т.е. 16*64К. Т.е. 1М. Но дос умела только 10 сегментов, которых хватало всем. Потому в большинство компов больше тупо не ставили.

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

Потому в большинство компов больше тупо не ставили.

В большинство компов тупо больше не ставили, потому что она (память) стоила баснословные деньги.

Хорошо, что ты почитал про этот процессор, теперь ты знаешь, как он адресовал память и какие у него были регистры. ;)

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

В большинство компов тупо больше не ставили, потому что она (память) стоила баснословные деньги.

включи голову. 640К стоили ровно в 1.125 раз дороже 720К. 1.125 это немного. Если завтра пачка сигарет будет стоить не 40, а 50 рублей, я курить не брошу.

Хорошо, что ты почитал про этот процессор, теперь ты знаешь, как он адресовал память и какие у него были регистры. ;)

я это читал, когда был школьником.

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

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

facepalm.

i-rinat ★★★★★
()
Ответ на: комментарий от emulek

я это читал, когда был школьником.

Все таки есть польза от этой википедии. А где ты прочитал про глюки и проблемы или кто-то из одноклассников говорил?

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

Все таки есть польза от этой википедии. А где ты прочитал про глюки и проблемы

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

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

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

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

Ты что несёшь тупорылое животное. Для идиота повторю - есть 2реализации кусорта в плюсах - это libc qsort() и stl - это std::sort(). Вот идёшь животное и думаешь - почему std::sort() работает быстре qsort(), хотя код такой же.

А потом ссанина ты идёшь и думаешь - почему stl, буст и прочее - это хеадер онли(овновной функционал) либа.

Какие инты, что сравнивают и твой жалкий кукаретинг мне не интерсен. Кукарекай дальше.

Макака, повторю вопрос - где твой код? Покажи мне его - яхоть поржу.

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

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

ну вот, всё есть:

Compilers for the 8086-family commonly support two types of pointer, near and far. Near pointers are 16-bit offsets implicitly associated with the program's code and/or data segment and so can be used only within parts of a program small enough to fit in one segment. Far pointers are 32-bit segment:offset pairs resolving to 20-bit external addresses. Some compilers also support huge pointers, which are like far pointers except that pointer arithmetic on a huge pointer treats it as a linear 20-bit pointer, while pointer arithmetic on a far pointer wraps around within its 16-bit offset without touching the segment part of the address.

To avoid the need to specify near and far on numerous pointers, data structures, and functions, compilers also support «memory models» which specify default pointer sizes. The tiny (max 64K), small (max 128K), compact (data > 64K), medium (code > 64K), large (code,data > 64K), and huge (individual arrays > 64K) models cover practical combinations of near, far, and huge pointers for code and data. The tiny model means that code and data are shared in a single segment, just as in most 8-bit based processors, and can be used to build .com-files for instance. Precompiled libraries often came in several versions compiled for different memory models.

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

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

ты вообще понимаешь, что такое >64K кода, не? Это тебе не сишарп и даже не сишка.

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

Я тебе повторяю, я много лет писал под дос. И про модели памяти все знаю, и что такое exe файл с relocation table, и что такое far/near. Давно это правда было, но вроде помню. :)

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

Ты что несёшь тупорылое животное. Для идиота повторю - есть 2реализации кусорта в плюсах - это libc qsort() и stl - это std::sort(). Вот идёшь животное и думаешь - почему std::sort() работает быстре qsort(), хотя код такой же.

а свой qsort ты не осилил сделать? Или осилил, но не дождался завершения?

А потом ссанина ты идёшь и думаешь - почему stl, буст и прочее - это хеадер онли(овновной функционал) либа.

я знаю. А вот ты — задумайся, детка. Для начала попробуй сам, ручками написать.

Макака, повторю вопрос - где твой код? Покажи мне его - яхоть поржу.

какой «мой», если ты спрашиваешь std vs glibc? А мой рвёт и то и другое.

Какие инты, что сравнивают и твой жалкий кукаретинг мне не интерсен. Кукарекай дальше.

дык где твой-то код? Начало за тобой, это же ты меня учишь жить. Не? Я же анскильная лолка, а ты — царь. Вот и демонстрируй, каков ты монарх. А я, смерд поганый, учится буду.

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

действительно. Зачем я рассказывал... У царя бесконечный цикл за 5 секунд прогоняется.

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