r90 в принципе, ничего секретного тут нет gcc http://gcc.gnu.org/onlinedocs/gcc-4.5.0/gcc/Optimize-Options.html#Optimize-Options действительно, -О2 это дальнейшее расширение -О1, но более в сторону ускорения кода (increases ... the performance of the generated code). cl пруфлинк - cl /? ну и совсем простой пример. уже предлагал его. есть такая система "инферно". одна из важных частей ее называется "emu". она написана на ансиС без использования каких либо фреймворков и даже С-рантайм для увеличения переносимости, что позволяет исключить внешние помехи. я ее достаточно беспроблемно компилил на выни, лини и п9, те компилируемость проверена. код за исключением нескольких платформозависимых файлов там общий. в свое время, экспериментируя, я собрал "ему" на cl -O1 в 700-800кб. ватком показал близкие результаты. доказательство. попробуйте добиться подобного размера с гцц (не обязательно O1)? можно и нерабочую сборку. там 3 файла не переносят омиченье хидеров. соберете - посмотрю какие. сорцы http://code.google.com/p/inferno-os/ захотите попробовать, но не поймете как собирать - пишите, посмотрим.
cppasm цитаты из мана и предложение эксперимента в посте выше. вам скорости по всей проге от начала и до конца не хватает?? интересно, что ж вы такое пишете и, боюсь даже заикнуться, как? большую часть проги можно вообще на скриптах без двойной трансляции писать (скрипты без двойной трансляции, а не писать без 2ной трансляции). а вот лишние мегабайты тела мне ж самому оплачивать гоняя их по 1000 раз через инет. кроме того, люблю я все компактное и ловкое. и ненавижу огромные свалки, хотя у них и вид впечатляющий. сразу видно люзьеру, что людья рамбонтале, скоко вло'жили. сразу проникаешься отчего оно полчаса загружается. (извините, не сдержался. с детства типает от халтуры. к вам не относится. просто вспомнил неро-шовтайм. вот чего надо компилить с 3мя -O2)
Если ты не выдашь мне скрипт конфигурации для этой поделки, то за простой пример не канает. У меня нет никакого желания разбираться с тем, что такое mk, и сколько же всяких разных файликов разбросанных по дереву сорцов мне надо подредактировать, чтобы получить рабочую конфигурацию. Я вышел из того возраста, когда на голом энтузиазме можно страдать такой фигнёй. Последние пять лет я ленюсь даже ./configure && make && make install сделать, и даже от asdf-install отказался в пользу того же emerge. А ты мне тут подсовываешь такое.
r90 я гдето оскорбил вас? или у вас уже были разногласия с любителями п9-инф? отчего тогда такое сверхнее отношение? и ко мне и к этой интереснейшей вещи, которую, впрочем, я не предлагаю и не рекламирую. не важно что это и зачем это. важно только то, что оно может быть легко скомпилено под кучу архитектур в одних и тех же сорцах, что позволяет испытать оптимайзеры компилеров. скомпилить достаточно просто. хотя, как вы понимаете, для того чтобы компилилось под многие архитектуры, с разными наборами утилит, часть тулзов используется собственная. тот же mk, который просто мэйкер. итак, 0) таки слить сорцы 1) добавить в паф путь к папочке <путь к сорцам инф>/<имя оси (Нт/Линь/Фря етк)>/<имя проца (386/арм етк)>/bin в ней живут необходимые добавочные утиля. например, mk 2) не забыть скреатить папочку <путь к сорцам инф>/<имя оси (Нт/Линь/Фря етк)>/<имя проца (386/арм етк)>/lib фиг знает чего они их поудаляли. были какието мутные объяснения. но факт, что они нужны под либы далее в корне сорцов 3) открыть в редакторе mkconfig и исправить ROOT= .... на правильный полный путь к сорцам от глобального корня SYSHOST= ... на название оси на которой компилится. варианты указаны в комменте OBJTYPE= ..... на название проца. опять же список в комменте. (ессно, должно быть поддержано в сорцах. те, должна существовать соотв подпапка в папке имени оси) 4) ну а далее mk all или mk install 5) если mk у вас не захочет работать, то попробуйте его пересобрать. для этой цели скрипт makemk.sh в нем также надо в начале поправить ROOT=/usr/inferno SYSTARG=FreeBSD OBJTYPE=386 SYSTYPE=posix также как и выше 6) после компиляции "emu" будет лежать в папке $ROOT/emu/Linux и называться как нибудь вроде "iemu" или "o.emu" (при mk all). или при mk install <путь к сорцам инф>/<имя оси (Нт/Линь/Фря етк)>/<имя проца (386/арм етк)>/bin/emu в случае линя 386, сорцы в /home/user/inferno это будет в /home/user/inferno/Linux/386/bin/emu где править опции оптимизации. все частные куски мэйкфайлов для разных дел и разных платформ собраны в ./mkfiles от корня сорцов куски с флагами для разных компилеров/линкеров называются mkfile-<ось>-<проц> те для выни 386 это будет mkfile-nt-386 а для лини 386, соответственно, mkfile-linux-386 вроде все написал. все просто. компилится достаточно быстро. если еще чтото вспомню, то допишу. или вы спрашивайте. (если вы вдруг захотите проверить сборку на рабочесть, то просто так "ему" не запустится. ему обязательно надо указать на текущий корень (в данном случае будет совпадать с корнем сорцов). например, emu -r/home/user/inferno или emu -r/home/user/inferno wm/wm или в переменной EMU) ЗЫ по секрету, а сколько вам лет?
cppasm Не-а... студия не помню еще с каких времен делает MOV'ами в развернутом цикле. А размер - ну скажем, 4К. На мелких-то - до 64 он вообще в мувы разворачивает. Хотя студия и тут потенциально лучше, поскольку разворачивает нелинейно. Хотя... может и мелкий, на крупном-то оно вообще по идее инлайнить не должно. Надо посмотреть как-нибудь...
qqwe Разве я выгляжу оскорблённым? Просто я не люблю связываться с софтом, который собирается путём неочевидных плясок с бубном. К plan9 я отношусь с умеренным любопытством, но именно с умеренным, поскольку не вижу для себя причин с ним связываться. Что такое inferno я даже не знаю, если честно, наверное, какая-то утилита под plan9, портированная везде. Пропуская пассаж, об обоснованности использования рукотворных утилит, скажу что я сделал всё, что в цитате спрятал за символами [...], вплоть до пункта 6. Собственно взбесила меня необходимость выяснять содержимое всех этих пунктов, методом исследования процесса сборки. До пункта 6 я не добрался, поскольку необходимое условие "после компиляции" не выполнено: компиляция не прошла. У меня есть дикое предположение, что если взять ./limbo/o.out, переименовать его в ./Linux/386/bin/limbo, то компиляция пройдёт дальше ещё на несколько шагов. Но мой энтузиазм уже закончился. Тем более, что меня сильно смущает 386 в качестве платформы: моя платформа amd64. Вообще, конечно же, я являюсь благодарным подписчиком оверлея multilib, и наполнение директорий /lib32 и /usr/lib32 у меня достаточно богато, но тем не менее, я не могу быть твёрдо уверен в том, что эта вещь запустится на моей системе без того, чтобы я ещё десяток библиотек собирал бы с USE-флагом lib32. Ustus Ну, мне кажется, что забота о правильном memcpy -- это забота libc, или я не прав? Ну, по-крайней мере, если заглянуть в сорцы linux, мы увидим там грядку функций memcpy, на всякие разные случаи: inline версии для маленьких размеров, которые разворачиваются полностью, версии для копирования int'ами, а не char'ами и тд, и тп. Плюс я как-то развлекался -- пытался обойти по скорости реализацию memcpy из libc: на больших объёмах данных, я сделал это используя sse, и кажется мне, что это уже не задача компилятора, заниматься такими фишками. Но, как бы там не было, я посмотрел, что делает gcc. Взял вот такую функцию: Код (Text): int tmp (char *a, char *b, int size) { int i; for (i = 0; i < size; i ++) { a[i] = b[i]; } } Если включать -O2, то gcc делает так: Код (Text): .L3: movzbl (%rsi,%rcx), %eax #* ivtmp.30, tmp67 movb %al, (%rdi,%rcx) # tmp67,* ivtmp.30 addq $1, %rcx #, ivtmp.30 cmpl %ecx, %edx # ivtmp.30, size jg .L3 #, Если же добавить -funroll-loops, то получается что-то типа: Код (Text): tmp: .LFB36: testl %edx, %edx # size jle .L5 #, movzbl (%rsi), %eax #* b, tmp67 leal -1(%rdx), %r8d #, tmp72 movl $1, %ecx #, ivtmp.30 andl $7, %r8d #, tmp72 cmpl $1, %edx #, size movb %al, (%rdi) # tmp67,* a jle .L37 #, testl %r8d, %r8d # tmp72 je .L3 #, cmpl $1, %r8d #, tmp72 je .L30 #, cmpl $2, %r8d #, tmp72 .p2align 4,,5 je .L31 #, cmpl $3, %r8d #, tmp72 .p2align 4,,5 je .L32 #, cmpl $4, %r8d #, tmp72 .p2align 4,,5 je .L33 #, cmpl $5, %r8d #, tmp72 .p2align 4,,5 je .L34 #, cmpl $6, %r8d #, tmp72 .p2align 4,,5 je .L35 #, movzbl 1(%rsi), %ecx #, tmp90 movb %cl, 1(%rdi) # tmp90, movl $2, %ecx #, ivtmp.30 .L35: movzbl (%rsi,%rcx), %r10d #* ivtmp.30, tmp91 movb %r10b, (%rdi,%rcx) # tmp91,* ivtmp.30 addq $1, %rcx #, ivtmp.30 .L34: movzbl (%rsi,%rcx), %r11d #* ivtmp.30, tmp92 movb %r11b, (%rdi,%rcx) # tmp92,* ivtmp.30 addq $1, %rcx #, ivtmp.30 .L33: movzbl (%rsi,%rcx), %eax #* ivtmp.30, tmp93 movb %al, (%rdi,%rcx) # tmp93,* ivtmp.30 addq $1, %rcx #, ivtmp.30 .L32: movzbl (%rsi,%rcx), %r8d #* ivtmp.30, tmp94 movb %r8b, (%rdi,%rcx) # tmp94,* ivtmp.30 addq $1, %rcx #, ivtmp.30 .L31: movzbl (%rsi,%rcx), %r9d #* ivtmp.30, tmp95 movb %r9b, (%rdi,%rcx) # tmp95,* ivtmp.30 addq $1, %rcx #, ivtmp.30 .L30: movzbl (%rsi,%rcx), %eax #* ivtmp.30, tmp96 movb %al, (%rdi,%rcx) # tmp96,* ivtmp.30 addq $1, %rcx #, ivtmp.30 cmpl %ecx, %edx # ivtmp.30, size jle .L38 #, .L3: movzbl (%rsi,%rcx), %r9d #* ivtmp.30, tmp75 movb %r9b, (%rdi,%rcx) # tmp75,* ivtmp.30 movzbl 1(%rsi,%rcx), %r8d #, tmp77 movb %r8b, 1(%rdi,%rcx) # tmp77, movzbl 2(%rsi,%rcx), %eax #, tmp79 movb %al, 2(%rdi,%rcx) # tmp79, movzbl 3(%rsi,%rcx), %r11d #, tmp81 movb %r11b, 3(%rdi,%rcx) # tmp81, movzbl 4(%rsi,%rcx), %r10d #, tmp83 movb %r10b, 4(%rdi,%rcx) # tmp83, movzbl 5(%rsi,%rcx), %r9d #, tmp85 movb %r9b, 5(%rdi,%rcx) # tmp85, movzbl 6(%rsi,%rcx), %r8d #, tmp87 movb %r8b, 6(%rdi,%rcx) # tmp87, movzbl 7(%rsi,%rcx), %eax #, tmp89 movb %al, 7(%rdi,%rcx) # tmp89, addq $8, %rcx #, ivtmp.30 cmpl %ecx, %edx # ivtmp.30, size jg .L3 #, Чёт, вы не так делаете.
r90 Может быть опции -O2 -furoll-loops и все? А какая версия gcc ? Еще может быть, что меня память подводит (давно этим занимался) и, может быть, что описаное мной поведение свойственно не memcpy, а memset. Хотя изучать красивость кода - эстетство, надо скорость мерить для объективной оценки. Но скажу сразу, что я со студией тоже гонялся еще с 2005-й, без MMX/SSE и результат был не в мою пользу
Почитать мануал, аппаратно ускорено с Pentium 4. Студия вызывает функцию CRT, раньше делала rep movs.
Спор ни о чём. Студия, как и многие другие нормальные компиляторы (GCC, Intel C++ ...), вставляет различный код в зависимости от размера копируемого блока: 1. замена серией mov 2. rep movsd+rep movsb 3. вызов memcpy из CRT
Хороший он код генерирует. Только надо CRT патчить. С родным CRT скомпилированные программы не используют MMX, SSE и т.д. расширения на не-Intel процессорах даже если расширения присутствуют. Проверяется имя процессора на GenuineIntel. Ищите в объектниках строку и патчите проверку имени. В остальном хорошо всё, даже очень.
J0E Хреновенько оно ускорено. Цикл все равно будет быстрее, кроме разве что совсем маленьких объемов.
r90 прошу прощения за долгий неответ. много писать пришлось. а потом, много сокращать. ну, в принципе, я в основном перевел часть install файла. немного подробнее чем, но это для солидности. все куда проще, чем компиление через ./configure ; make с нестандартными опциями не. инферно это и есть п9, но имеющий ко всему прочему еще и жит компилирующую вм (та же идея, что и у жабы), работающего от языка возникшего от скрещения упрощенного алефа с обероном. оно отщепилось еще во времена п9-2. те, около 95 года. но вскоре после этого беллабс пошли с молотка несколько раз подряд и план почти перестал интересовать нового хозяина, его разрабы перешли кто куда. в основном, смотрю, в гугль, где строгают щас реинкарнацию лимбо - го. инферно выкупил один из разрабов - форсит, перевез к себе в англию и постепенно снизил цену за инсталляцию с $1000 или сколько там практически до гпл. в настоящее время инферно это скорее такой себе фреймворк, позволяющий запускать скомпилированные лимбо модуля (наследство оберона) без перекомпиляции на любой из платформ под которых существует "ему". или на голом железе. причем, жит компилятор достаточно хорош и модуля гоняют на глаз не медленнее, чем на С. ну и вм с нужной машкод обвязкой ("ему") занимает < 800кб (у меня. а так, в среднем метр-два). все настройки очень простые. как в плане. вот пример простой п2п чатилки на лимбо + инф. (функции шифрования инф выполняет само. если указать ессно) Код (Text): # -- server limbo prog --- VVV ------------------------- implement hw_nc2; include "sys.m"; include "draw.m"; sys : Sys; wdir := "/n/-"; hw_nc2: module { init: fn(ctxt: ref Draw->Context, argv: list of string); }; init(nil: ref Draw->Context, nil: list of string) { sys = load Sys Sys->PATH; sys->bind("#s", wdir, Sys->MREPL); ioch := sys->file2chan(wdir, "ch"); spawn read_write(ioch); } read_write(ch : ref Sys->FileIO) { while(1){ alt { #-------------- (offset, count, fid, rc) := <-ch.read => if(rc != nil){ prmpt := array of byte "\n# "; b := array[count] of byte; f := sys->open("/fd/1", sys->OWRITE); sys->write(f, prmpt, len prmpt); f = sys->open("/fd/0", sys->OREAD); res := sys->read(f, b, len b); if(res > 0){ rc <- = (b[ : res - 1], ""); }else{ rc <- = (nil, ""); } } #-------------- (offset, data, fid, wc) := <-ch.write => if(wc != nil){ sys->print("\nwrite off = %d, id = 0x%X\n%s\n", offset, fid, string data ); wc <- = (len data, ""); } #-------------- } } } # -------AAA--------------------------------------------------------------------------- after #server: ; listen -A tcp!*!8080 export /n/- #client: ; cs ; mount -A tcp!ip_of_server!8080 /n/- ; cat /n/-/ch after #server: ; cat > /n/-/ch # - wrote messages #client: # - reads them в общих чертах гдето так. по шеллу инф и п9 похожи. есть гдето пример брутилки инет пасов на инферно шелле и клиента базы данных (удаленной/локальной. для инф/п9 это практически неважно. даже устройства могут шариться удаленно.) мнээ.. хорошо бы примеров.. примеров есть даж не знаю с чего начать.. вот тут куча всяких несложных http://caerwyn.com/ipn например, этот (реализация простой теговой фс на инферно/п9 шелле) http://caerwyn.com/ipn/2005/08/lab-41-venti-lite.html или это. (даже не совсем понял что это чтото насет музыки) http://caerwyn.com/ipn/2004/09/lab-7-sequencer.html есть там как минимум 1 кластер, 1 песочница по типу задуманной рутковской итд. есть на что посмотреть, вобщем. насчет компиления в 64 бита. там в общем то не так много предположений о разрядности и асм вставок. разговор о добавлении 64 битных кусков был. пока не дописали до конца, я так понял, изза необходимости соблюдать полную переносимость. но процесс идет. насчет мк мк это стандартный мэйкер из плана. существует с 91 года. он достаточно маленький, быстрый и мощный. а через инферно еще и перенесенный на кучу платформ. это удобно и, например, я его юзаю для разных целей. также как и остальные инф утили. насчет лимбо лимбо, как и все утили существуют в 2х вариантах. нативном и дис. нативный используется только для сборки. нативное лимбо используется после сборки emu. если у вас тормознуло на нем, то emu уже собрано. как минимум, можно посмотреть насколько съоптимизировало. а можете его и запустить. и или взять готовое дис - дерево. или скомпилить все из emu. emu не пользуется бинарными утилями и имеет собственное файловое дерево, хотя можно вызывать и броузить и то и то #вызов внешнего бинаря ; os <внешний бинарь по правилам оси хозяйки> #подключение внешнего файлового дерева (корень) к папке /n/local. при этом, файлы (в том числе и подключенные, и удаленные, и именованные каналы) уже находящиеся в ней остаются видны и доступны ; bind -b '#U*' /n/local или например ; bind -b '#U*/home/user/desktop' /n/local насчет п9 п9 тормознулась в свое время сперва изза неправильной ком политики (сильно много хотели), а потом изза банкротства белов и серии перепродаж. счас оно свободно и бесплатно (с оговоркой). ось на мой взгляд очень интересна как инструментальная среда. интересна изза легкости, высокой перестраиваемости. все ядро и не только ядро представляет собой набор п9 серверов сообщающихся по достаточно простому, перенаправляемому на сеть, протоколу. это очень близко к микроядеркам. но п9 по дефолту собирается как композитка. изза встроенной оч сильной поддержки сети, большие возможности по расшариванию ресурсов, по реконфигурации среды (вплоть до получения каждой аппликухой собственного варианта файлового дерева. например, чтоб отснифать весь обмен апликухи, в том числе и с прямыми вызовами ядра, совсем не обязательно лезть в ядро, писать спецдрова. тоже и с протоколами итд. подозрительной проге достаточно несложно подсунуть вместо реальных файлов обманку, где она не сможет обратиться к файлам напрямую. те запустить - да, прочитать - да, записать - да. но слить в инет или записать - только под комролем. даже через int. впрочем, это трудно объяснить. в плане все файлы - именованные каналы и только их сервера знают наверяка что это за. и врезаться между прилогой серве.. увлекся чето. извиням), мощной многопоточности итд. утверждают, что имеет 2 планировщика. реалтайм и обычный в принципе п9 и инферно - это юникс, каким бы он мог быть, если б шел по изначальной задумке планов. щас а него накручено много отвлеченного, хотя он пока и не так похож на кучу заплаток, как вынь ЗЫ вот тут http://code.google.com/p/inferno-bin/ несколько уже собраных emu для разных платформ. можно попробовать. если запустится, то зачем собирать в 64 бита? регардс
Не понял к чему это. В приложении что-ли патчить? Там CRT несколько вариантов - динамическая (dll) и статическая в нескольких версиях. Проще один раз запатчить obj и dll чем потом каждое собранное приложение патчить. Описание чего и как есть здесь: http://www.swallowtail.org/naughty-intel.shtml И у Агнера Фога: http://www.agner.org/optimize/blog/read.php?i=49 Плюс у него в мануале по оптимизации в С++ (http://www.agner.org/optimize/optimizing_cpp.pdf) в разделе 13.5 описано как это убрать без патча - типа легальными методами. Надо свою функцию диспетчеризации написать с тем же именем что оригинальная, и она перекроет оригинальную из CRT при линковке. Но это подходит только для статической CRT.
20 это к оптимизатору студии, если копируется блок меньшего размера, то будут (rep) movs, иначе call memcpy. Но цифра не точна, смотрел давно и
Только что проверил на VS2008 express - там сложнее всё. Ключи /Ox /Ob2, размер блока: 0-22, 24 (т.к. кратно 4): серия из mov 23, 25-4К: rep movsd +movsw+movsb для хвоста блока >=4K: crt memcpy