Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > C/C++: Для новичков > msvc2008 bug??? |
Автор: GoldFinch 6.12.2008, 19:14 | ||||
это баг или "фича"? о_О |
Автор: Kallikanzarid 6.12.2008, 19:23 |
А что ты ожидал? В ebp хранится указатель на фрейм: http://en.wikipedia.org/wiki/Frame_pointer |
Автор: GoldFinch 6.12.2008, 19:33 |
Kallikanzarid, фрейма нету, какбэ читай код в 1м посте полностью |
Автор: MAKCim 6.12.2008, 19:44 |
GoldFinch, хм, реально баг получается |
Автор: Kallikanzarid 6.12.2008, 20:03 |
Точно, должно быть esp ![]() Попробуй поставить сервис пак, может, поможет. |
Автор: J0ker 7.12.2008, 01:01 |
все верно в прологе esp сохраняется в ebp, и от ebp считаются аргументы так что все правильно неправильно в naked использовать аргумент - т.к. компайлер плюет, что вы отказались от пролога и эпилога |
Автор: dumb 7.12.2008, 04:46 |
хм. http://msdn.microsoft.com/en-us/library/4d12973a(VS.80).aspx про аргументы ничего такого не сказано, однако упомянуто авто-отключение Frame pointer optimization для naked функций. т.е. компилер рассчитывает на то, что руками фрэйм таки будет создан, что он и демонстрирует. |
Автор: Kallikanzarid 7.12.2008, 08:54 |
GoldFinch, Если нет желания использовать фрейм, попробуй __fastcall. ЕМНИП, два двойных слова ты с его помощью без проблем передашь даже без фрейма. В принципе можно одним из них передавать указатель на объект, в котором хранятся остальные параметры. |
Автор: J0ker 7.12.2008, 09:04 |
ну прям лень фрейм выставить - 2 инструкции в начале и 2 в конце |
Автор: GoldFinch 7.12.2008, 10:29 |
Kallikanzarid, в
msdn сказано что при __fastcall компилятор не гарантирует очередность
параметров, т.е. неизвестно какой окажется в eax а какой edx. Кроме
того, в большинстве случаев аргументы лежат в стеке. J0ker, я привык к тому что когда я пишу на асме, я пишу как я хочу, а не так как того хочет конпилятор. может у меня ограничения на длину кода, мне тогда этот фрейм впихнуть некуда, более того, он в ряде случаев просто не нужен. |
Автор: Kallikanzarid 7.12.2008, 14:26 |
GoldFinch, Если
бы ты писал под мобильники, то юзал бы явно не студию. Уменьшение
размера кода даже на килобайт абсолютно незаметно. Теоретик, блин ![]() ЗЫ: Зачем тебе нужны naked функции? Кстати, если тебе так противен фрейм, можешь спокойно высчитывать расположение параметров сам. |
Автор: GoldFinch 7.12.2008, 15:20 |
Kallikanzarid, если бы ты писал на асме, ты бы знал зачем надо уменьшать код, зачем нужны naked функции высчитывать расположение параметров самому глупо, этим должен заниматься компилятор, тем более что это асм встроенный в ЯВУ |
Автор: Kallikanzarid 7.12.2008, 15:45 | ||||||
О да, я такой глупый, просто оторопь берет! ![]() Ты хоть профилировщик запускал прежде, чем прибегать к таким мерам? Или тебе 4мб L2-кэша заранее мало?
Писать пролог самому глупо, этим должен заниматься компилятор. ЗЫ:
А тебе зачем это знать? Обращайся к параметрам по имени. |
Автор: GoldFinch 7.12.2008, 16:37 | ||
Kallikanzarid, вот есть у меня например такой код:
куда здесь воткнуть ebp фреймы? |
Автор: Kallikanzarid 7.12.2008, 16:45 |
Боюсь даже представить ![]() |
Автор: dumb 7.12.2008, 16:53 |
чем бы не тешилось... сам же запутаешься в этом г..не(иных слов не подбирается) через неделю. остается надеяться, что эти извращения не имеют отношения к чему-то, чем будут пользоваться люди. |
Автор: GoldFinch 7.12.2008, 17:01 |
реализует "ленивые" импорты да там же все понятно, что он делает, всего-то десяток строчек |
Автор: GoldFinch 7.12.2008, 17:46 |
dumb, это
хорошо, что ты не понял этого кода. Он призван вызывать священный
трепет, а то и ужас, перед асмом у тех ламеров, кто полезет с ИДА
узнавать какие импорты юзаются в моей проге. Хотя код крайне тривиален,
я думаю найдется немало людей которые испугаются увидев это, и не
станут копать мою прогу. =) |
Автор: Kallikanzarid 7.12.2008, 17:51 | ||
Главное, чтобы босс был не в их числе ![]() |
Автор: GoldFinch 7.12.2008, 19:34 |
J0ker, впринципе логично, что компилятор не разбирает асм-код хотя могли бы это и сделать... не бином ньютона =\ |
Автор: J0ker 7.12.2008, 19:38 |
бином предположим, ты выделяешь на стеке массив с размером, взятым из одного из параметров - в стиле C99 |
Автор: GoldFinch 7.12.2008, 19:45 |
J0ker, хм... ну тогда стоило бы выдавать ошибку компиляции, или хотябы явно написать об этой "фиче" в документации %) |
Автор: J0ker 7.12.2008, 20:23 | ||||
http://msdn.microsoft.com/en-us/library/5ekezyy2(VS.80).aspx http://msdn.microsoft.com/en-us/library/4d12973a(VS.80).aspx
|
Автор: GoldFinch 8.12.2008, 00:46 | ||
раз уж речь пошла о пользе naked, подскажите как тут избавиться от асма:
|
Автор: mes 8.12.2008, 10:52 |
![]() ![]() |
Автор: Kallikanzarid 8.12.2008, 11:07 |
GoldFinch, ur crazy ![]() Пожалуйста, скажи, что это профайлер показал, что необходимо вручную передавать параметр через регистр. Или использовать глобальную переменную. Или вручную расчитывать смещение поля в объекте (ничего, кстати, что это нарушает инкапсуляцию?). Не говоря уже о том, что рекомендуется передавать объекты по ссылкам, а не по указателям. Я начинаю боятся за будущее Земли. ЗЫ: твой код неэффективен. Ты два раза заносишь в стек один и тот же параметр. Настоящий Программист бы сделал так, чтобы функция Render после вызова оставляла его в стеке, а функция OnRender - использовала повторно. Ты неэффективен! |
Автор: dumb 8.12.2008, 11:40 |
тьфу ты. неужели вместо
того, чтобы нормально описать ситуевину, мол "развешиваю хуки в
игрушке", надо было "выеживаться" в потугах самоутверждения?
этот вопрос риторический. в данном случае избавляться от асма imho особого смысла нет - тебе нужно сделать совершенно определенные низкоуровневые трики, и если их пытаться переписать на С, получишь кучу неоднозначностей и условностей, не говоря уже о том, что код получится, скорее всего, гораздо менее "прозрачным". так же как и нет смысла вкрячивать в высокоуровневый код примитивную защиту извращаясь с дефайнами и вставками - для снятия оной вовсе не обязательно, чтобы механизм понимал любой "ламер" - достаточно одного немного продвинутого заинтересованного человека. mes, Kallikanzarid, вы не учитываете того, что работа идет с готовым бинарным кодом. товарищ путем предоставления обрывков информации по сути провоцирует нас на такие бессмысленные(в конечном счете) комментарии. |
Автор: Kallikanzarid 8.12.2008, 12:10 |
Чьорт, меня затроллил закомплексованный труъ-ассемблерщег ![]() |
Автор: ksili 8.12.2008, 12:26 |
Прикинь, я пишу под WinMobile и использую-таки студию |
Автор: mes 8.12.2008, 12:42 |
Вместо того чтоб учитывать все возможные предположения, которых в действительности может и не быть (так как в другом топике этого же автора вроде (может и ошибаюсь) подразумевалось о том что исходники на руках) лучше было бы если бы автор описал бы свою ситуацию. Без этого будет имхо затруднительно ответить на вопрос: |
Автор: GoldFinch 8.12.2008, 13:06 | ||
Kallikanzarid, "рекомендуется
передавать объекты по ссылкам, а не по указателям" я кнешно не
силен в С++, но какая между ними разница? о_О dumb, какая разница, для чего нужен код? хуки они и есть хуки... а использование ЯВУ вместо такого асма позволит значительно повысить читаемость:
ЗЫ: а та "примитивная защита" не хуже, чем популярное криптование символьных имен или импорты по хешам. К тому же ей гораздо удобнее пользоваться, т.к. функции(методы) вызываются нормально, а не по указателям. |
Автор: Kallikanzarid 8.12.2008, 13:09 | ||
Поди еще .NET используешь ![]() Добавлено через 7 минут и 25 секунд GoldFinch, ссылка на протяжении своей жизни гарантированно указывает на один и тот же объект, то позволяет компилятору включить множество оптимизаций, которые он (справедливо) боится применять к указателям. http://www.tantalon.com/pete/cppopt/main.htm - устаревший ресурс, но многое все еще справедливо. Защита дефайнами и вставками элементарно ломается с помощью препроцессора. |
Автор: ksili 8.12.2008, 13:16 |
Не, чисто на С++. |
Автор: GoldFinch 8.12.2008, 13:27 | ||
как это? какого препроцессора? о_О |
Автор: Kallikanzarid 8.12.2008, 13:31 |
GoldFinch, Препроцессора С/С++. Прогоняешь через него файлы, и дефайны со вставками волшебным образом исчезают ![]() ksili, как я понимаю, речь идет о смартфонах? Я имел ввиду, что экономить 10 байт может иметь смысл лишь с очень ограниченными платформами, вроде старых мобильников. |
Автор: ksili 8.12.2008, 13:37 | ||
Да, смартфоны, КПК, ... это наш клиент ))
Не понял. Ломают обычно бинарник. Как ты его прогоняешь через препроцессор? |
Автор: Kallikanzarid 8.12.2008, 13:42 | ||
Тогда я ничего не понимаю ![]() |
Автор: mes 8.12.2008, 13:42 | ||
имелось ввиду несколько другое :
|
Автор: ksili 8.12.2008, 13:48 |
Не, ну вы все-таки
объясните. На С и асме пишется прога. Я так понимаю с расчётом на то,
что её будет сложно взломать, ну или просто разобраться в ее коде в
дизассемблере. Всё это предполагает то, что у злоумышленника будет
бинарник, и не будет исходников. Что тогда такое "дефайн" в исполняемом файле? Что исчезнет в таком файле, после его прогона через препроцессор? |
Автор: mes 8.12.2008, 14:04 | ||||
по контексту речь идет о некоторых программистах, которые "портят" (с какой целью можно только предполагать) исходный код :
|
Автор: GoldFinch 8.12.2008, 14:10 | ||
Kallikanzarid, речь шла от такой защите дефайнами и асм вставками
после автоанализа в ИДА бинарник выглядит весьма неплохо, на 1й взгляд, да и на 2й взгляд там будет немало возни с восстановлением импортов. и это еще самый простейший вариант) |
Автор: mes 8.12.2008, 14:23 | ||
![]() только ради (мнимой) надежды что код не взломают ? В принципе могут и не взломать.. это если как в анекдоте про неуловимого Джо... ;) |
Автор: ksili 8.12.2008, 14:23 |
Короче мы (GoldFinch, Kallikanzarid, mes и я) в этой теме - лебедь, рак и щука, и ёщё кто-то четвёртый ![]() ![]() |
Автор: GoldFinch 8.12.2008, 14:35 |
mes, возни мало, зато куча преимуществ. статический импорт не работает, т.к. для него надо иметь заголовочные (.h) файлы идентичные тем что были использованы при компиляции длл, иначе возникает несоответствие таблиц методов. динамические импорты через getprocaddress неудобны изза использования указателей на методы (obj->*met)() вместо obj->met() а такими приятно пользоваться в коде + их можно генерить скриптом |
Автор: mes 8.12.2008, 14:55 | ||||
забываете о прокси-классах типа умного указателя.
под одну платформу, определенный тип компилятора и небольшой плясочки, чтоб привести целевой бинарник к удобному виду. ) |
Автор: GoldFinch 8.12.2008, 16:05 |
кроссплатформенность С++ зачастую приводит к очень плохой кодогенерации. лучше уж генерить хороший код под одну платформу чем *плохой* но чтоб можно было под любую. когда я пишу код который будет работать внутри готового win32 приложения, мне эта кроссплатформенность *не нужна* |
Автор: Kallikanzarid 8.12.2008, 16:25 |
GoldFinch, [citation needed] |
Автор: GoldFinch 8.12.2008, 16:34 |
??? |
Автор: Kallikanzarid 8.12.2008, 16:50 |
Мне не кажется очевидным, что кроссплатформенный исходный код приводит к генерации "плохого" бинарного кода. |
Автор: GoldFinch 8.12.2008, 17:15 |
Kallikanzarid,
из-за "кроссплатформенности", в С(++) нет способа средствами языка
сгенерить некоторые x86-87 команды, например загрузку констант в
FPU. Т.е. в некроссплатформенном паскале есть оператор(функция) Pi который генерит fldpi, а в кроссплатформенном С(++) оператора Pi() нет, и способа сгенерить fldpi (и другие константы) тоже нет. Впрочем код C++ для FPU местами ужасен %) Ни один нормальный программист такого бы не писал. |
Автор: Kallikanzarid 8.12.2008, 19:33 |
Троллинг перерастает в холивар... ![]() 1) Чем плохи заранее обсчитанные константы? 2) Паскаль - не кроссплатформенный? ![]() 3) Меня ты продавишь только цифрами, так как плевать я хотел на красоту бинарного кода ![]() 4) А ты можешь вручную оптимизировать расположение инструкций, чтобы минимизировать простой конвеера? |
Автор: J0ker 8.12.2008, 19:35 | ||
бред никакой связи тут нет вопрос лишь в поддержке компилятора не существует "кода C++ для FPU" качество кода, сгенерированного компилятором зависит от качества компилятора оценка качества оптимизированного кода неподготовленными субъектами обычно неадекватна, т.к. понять что оптимально а что нет на уже 2-х процессорных платформах способен только специалист и вообще на 2-х последних страницах столько бреда, что ужасть ![]() |
Автор: GoldFinch 8.12.2008, 20:05 |
Kallikanzarid, 1) тем что аппаратные константы много лучше программных 2) паскаль - я имел ввиду турбопаскаль, дельфи 3) цифры: fldpi - 2байта pi dt 3.14.... / fld [pi] - 10+6 байт 4) если бы ты видел код который те генерит твой компилятор, ты бы не говорил о "минимизации простоя конвеера" какбэ вот такой код при конфигурации "релиз" - это реальность .text:1000122F mov eax, dword ptr [g_hEngine] .text:10001234 mov dword ptr [eax+56F5D8h], offset Hook_ALineagePlayerController_PlayerCalcView(AActor *,FVector *,FRotator *) .text:1000123E mov ecx, dword ptr [g_hEngine] .text:10001244 mov dword ptr [ecx+57B968h], offset loc_10001190 .text:1000124E mov edx, dword ptr [g_hEngine] J0ker, ок, будет говорить исключительно о компиляторе MSVC. так вот у него кодогенератор - гуан* насчет кода для FPU - вот так вот в MSVC передаются 32-разрядные значения float .text:10001344 fld [esp+18h+arg_4] .text:10001348 fstp [esp+18h+var_14] .text:1000134C fld dword ptr [eax+4] .text:1000134F fstp [esp+18h+var_18] .text:10001352 call FCanvasUtil::DrawLine(float,float,float,float,FColor,int) видимо те кто писали кодогенератор малость не учли, что dword'ы в стек можно запихивать командой push, а не через стек FPU %) |
Автор: Kallikanzarid 8.12.2008, 20:15 |
GoldFinch, объясняю еще раз для самых одаренных. Мне. Плевать. На. Красоту. Ассемблерного. Кода. Если бахвалишься своей труъ-ассемблерностью, подтверди свое превосходство, представив реализацию какого-нибудь численного алгоритма на С++ и на асме. И время, за которое эти реализации выполняются. |
Автор: GoldFinch 8.12.2008, 20:24 |
Kallikanzarid,
вот тебе какбэ алгоритм получения 80-разрядной константы Pi, разница в
размере - в 8 раз, разница в быстродействии в единицы - десятки раз, в
зависимости от расположения константы в кеше или нет. Не нравится - выбери другой алгоритм, метод, условия измерения и представь свой труъ С++ код, ато я на С++ меньше месяца пишу, могу true с false через strlen() сравнивать. |
Автор: J0ker 8.12.2008, 20:42 | ||
видимо тот, кто критикует то, что не понимает, не знает того, что преобразование типов в плавающую точку является реальной операцией, а не кастом на уровне переназвания типа |
Автор: GoldFinch 8.12.2008, 20:46 |
J0ker, и где же ты там преобразование увидел? я тольк увидел преобразование m32real->m80real->m32real. там какбэ fld а не fild |
Автор: J0ker 8.12.2008, 20:50 | ||
именно в функции операнды передаются через стек, и при передаче тип должен быть проверен и если он не может быть преобразован то в точке передачи обязан быть выставлен флаг исключения если данную функцию переписать как инлайн, то все будет оптимизированно на стеке FPU других решений тут нет и быть не может |
Автор: GoldFinch 8.12.2008, 20:56 |
а это не решение? о_О pushd [esp+18h+arg_4] pushd [eax+4] call FCanvasUtil::DrawLine(float,float,float,float,FColor,int) |
Автор: mes 8.12.2008, 21:08 |
битовое представление floata равного n не не соответствует битовому представлению этого числа в dword/int (дополненого нулями) |
Автор: J0ker 8.12.2008, 21:20 | ||
нет |
Автор: GoldFinch 8.12.2008, 21:21 |
mes, я струдом догадываюсь что такое битовое представление, тем более дополненное нулями О_о, и причем тут это команда push [mem32] копирует 4 байта по адресу mem32 в стек, и она не обращает внимания на "битовое представление" этих байт. J0ker, и в каком же месте это не решение? |
Автор: J0ker 8.12.2008, 21:29 |
в месте преобразования типа - размещение значений с плавающей точкой в памяти и обратная операция сопряжено с преобразованием типов нельзя корректно положить на стек число с плавающей точкой иначе чем через стек FPU |
Автор: mes 8.12.2008, 21:30 | ||||
сейчас набросаю пример почему не явлется решением :
Добавлено @ 21:33 вот примерно что получится в результате вашго решения :
|
Автор: GoldFinch 8.12.2008, 21:39 |
J0ker, mes, жжоте... какие громкие заявления) какая уверенность в правоте своих слов... вы не правы. Потому что черное это черное, а белое это белое. Есть много способов премещать значения в памяти, и если вы этого не знаете это не значит что эти способы неверны) Курите документацию к процу и вам откроется истина) Но какие замечательные высказывания от вроде бы малость разбирающихся в программировании людей... Записал бы, да бред не коллекционирую. upd: mes, нет, Ваш код ниразу не соответствует той ситуации. |
Автор: mes 8.12.2008, 21:49 | ||
никакой громкости.. Вам был представлен пример, который показывает что участок памяти трактованный как int, числено не равен этому же участку памяти но трактованному как float. жаль что Вы даже не захотели этого понять ;) И ночью тоже ?
а кто нибудь оспаривал ? речь не о перемещении а о трактовке значения. А вот это действительно громко. Записал бы, но .... я думаю Вы догадались ) |
Автор: J0ker 8.12.2008, 21:56 |
так..... тут было потерто обкидывание оппонента какашками ![]() |
Автор: mes 8.12.2008, 22:12 | ||||
вот немного изменил код, чтоб легче было понимать что происходит .. желаю приятных эксперементов :
|
Автор: GoldFinch 8.12.2008, 22:17 | ||
mes, что за бредовый пруфкод вы пишете? то что мы обсуждаем выглядит так:
в строчке "push dword ptr [arg]" float значение передается в стек через push а не через пару fld/fstp что характерно прога выводит "8/7==8/7" |
Автор: J0ker 8.12.2008, 22:25 |
GoldFinch, я вам объясняю... совершенно спокойно, вот... преобразование из дабл во флоат - это ОПЕРАЦИЯ - она не может быть выполнена без привлечения FPU либо его эмулятора если вы в своих примерах замените float на double вы сразу это поймете |
Автор: mes 8.12.2008, 22:28 | ||
A Вы схитрили .. перепешите код изменив эту срочку на int Bar(int arg) вот Вам каркас теста :
потом еше можете изменить int на double и посмотреть результат ) |
Автор: J0ker 8.12.2008, 22:39 | ||
GoldFinch, вот, разберитесь уже наконец
|
Автор: GoldFinch 8.12.2008, 22:39 | ||||
J0ker,
где Вы тут увидели double??? тот самый 64-разрядный double, а не 32-разрядный float?? надеюсь Вы понимаете что мы говорим о 32(тридцатидвух)-разрядных значениях?? но специально для Вас, я перепишу код для double, и даже уберу там баги которых Вы не заметили)))
какбэ 64-разрядные значения запихиваются в стек двумя push [mem32] более того, пиши я под x64, там был бы один push [mem64] Добавлено @ 22:44 J0ker, Вас в вашем коде строчки 00401658 fstp dword ptr [esp+4] 0040165C fld dword ptr [esp+4] не смущают? и вообще, как эта муть относится к теме? mes, медленно, вдумчиво, прочитайте еще раз этот код, и Вы поймете что Вы пишите не по теме. .text:10001344 fld [esp+18h+arg_4] .text:10001348 fstp [esp+18h+var_14] .text:1000134C fld dword ptr [eax+4] .text:1000134F fstp [esp+18h+var_18] .text:10001352 call FCanvasUtil::DrawLine(float,float,float,float,FColor,int) ну нету в этом коде ничего связанного с int, не-ту |
Автор: J0ker 8.12.2008, 23:04 | ||||
да я собстна не про этот код ![]() я его даже не читал
а вас смущает? а что вас смущает? ![]() когда вы это поймете, дискуссия будет окончена ![]() |
Автор: GoldFinch 8.12.2008, 23:09 |
J0ker, эти
строчки - nop. они ничего не делают. И таких строчек в том коде много.
Вы вообще смотрели тот код который выложили? Да там оптимизацией и не
пахнет. Добавлено через 6 минут По оптимизации - вот это вот 004016DE push ecx 004016DF fld dword ptr [esp+38h] 004016E3 fstp dword ptr [esp] 004016E6 call 00401650 заменяется на push dword ptr [esp+38h] call 00401650 и т.д. и т.п. не верите? проверьте в ольке |
Автор: J0ker 8.12.2008, 23:23 | ||||
да неужели? а давайте проверим - вот конкретно эти строчки
вы мысль улавливаете, да? ![]() Добавлено через 1 минуту и 32 секунды
только если нет преобразования типов ага ![]() |
Автор: GoldFinch 8.12.2008, 23:30 |
J0ker, уловил.
Только в чем смысл округления 80-разрядного значения в стеке
сопроцессора до 32-разрядного? Я чтото не представляю себе жизненных
случаев где это может пригодиться. Добавлено @ 23:33 мм... развечто при сравнении... так тогда и надо округлять перед сравнением, а не всегда и везде, иначе какая это оптимизация %) так или иначе, разговор начался с копирования float в стек, *уже округленного* float в стек. |
Автор: J0ker 8.12.2008, 23:36 | ||
в том, что вы не можете просто так отрезать лишние биты при трансфере чисел с плавающей точкой я совершенно согласен, что можно, и даже иногда нужно оптимизировать вычисления на FPU на ассемблере, т.к. стандартные типы пока не вмещают полноразмерные числа с ПТ но совершенно безосновательно возводить поклеп на умных людей написавших грамотный компилятор Добавлено через 10 минут
это вы знаете, что у вас там float, а процессору это нужно доказать ![]() |
Автор: GoldFinch 8.12.2008, 23:47 | ||||
Так я и не понял с этими отрезаниями..... У меня в памяти есть 32-разрядный float. Готовый, правильный, безо всяких подвохов float. Почему компилятор не копирует его в стек командой push [mem32], а генерит fld [mem32] / fstp [mem32] ?? В стеке же оказывается одно и тоже значение...
кто невмещает? в С++ нет 10-байтового вещественного чтоли? Добавлено через 2 минуты и 56 секунд действительно нет.... везде есть, а в С++ нет.... как же так %) |
Автор: J0ker 8.12.2008, 23:53 |
c'est la vie |
Автор: GoldFinch 8.12.2008, 23:53 | ||
что доказать???? 004016DE push ecx ; sub esp,SizeOf(dword) 004016DF fld dword ptr [esp+38h] 004016E3 fstp dword ptr [esp] 004016E6 call 00401650 float и dword это одно и то же, что тут доказывать процессору? |
Автор: J0ker 9.12.2008, 00:00 | ||
опа, вот и я не прав long double в стандарте оказывается... проморгал ![]() Добавлено через 2 минуты и 34 секунды
я ж вам уже сказал - что у вас там лежит в памяти известно только вам |
Автор: Kallikanzarid 9.12.2008, 00:27 | ||
Итак, it's a showdown!!! Алгоритм - интегрирование методом трапеций. Интегрируется косинус, при этом специально не используется его свойство периодичности. В общем, смотри код:
Код, кстати, кроссплатформенней некуда. Компилировал с помощью MinGW со следующими параметрами=: g++ -msse3 -mfancy-math-387 -m80387 -mhard-float -mtune=pentium4 -march=pentium4 -mthreads -mfp-ret-in-387 -mieee-fp -O3 -funroll-loops -o showdown.exe showdown.cpp После этого прогнал через strip: strip -s showdown.exe Прикладываю экзешник. Удачи, чувак ![]() |
Автор: GoldFinch 9.12.2008, 14:44 | ||
Kallikanzarid, ты бы перед тем как выкладывать код с бинарником, убедился бы в их качестве код - неудобный, хз как у вас а меня еще в школе учили в конце консольной программы вставлять паузу. функция - неоптимизирована, про использование for я вообще промолчу... а самое главное, в бинарнике видно что компилятор заинлайнил cosint() и заменил ее аргументы константами. получилось както так:
так и было задумано?) а что сразу так не написал?))) |
Автор: Kallikanzarid 9.12.2008, 15:09 |
GoldFinch, 1) За годы практики я убедился, встроенная в саму программу пауза - это зло. Намного лучше создавать для этой цели .bat-файл. 2) Я специально ничего не оптимизировал, чтобы функция выполнялась достаточно долго, и чтобы компилятор мог проявить себя в раскрутке циклов и т. д. 3) for и правда не самый оптимальный (и, к тому же, накапливающий погрешность), но мы ведь спорили об оптимизации FPU-кода, так? Вот я и стараюсь загрузить его по максимуму. 4) Инлайн есть гут ![]() 5) Да, так и было задумано ![]() Добавлено через 3 минуты и 8 секунд float вместо double я тоже использовал в своих корыстных целях, дабы векторизация дала прирост x4, а не x2. Хотя этот алгоритм не особенно хорош для SSE, так что, может быть, код там использует только FPU. Хз, я через BIEW не прогонял. |
Автор: GoldFinch 9.12.2008, 17:10 | ||
Решение "в лоб", без FPU-оптимизации, бинарник (2кб) в архиве
на моем компе код Kallikanzarid'а работает 704мс, мой код работает 563мс, 20% разница P4 3ГГц, WinXPSp2 |
Автор: Kallikanzarid 9.12.2008, 18:51 |
Хорошо... но недостаточно! Я немного подправил код, сделав цикл целочисленным. Это скостило совсем немного, зато точность возрасла до твоей. Зато потом я дорвался до документации GCC, хехе. В общем, качай. |
Автор: J0ker 9.12.2008, 19:34 |
Kallikanzarid, я те советую воспользоваться OpenMP и пусть GoldFinch, попробует угнаться ![]() |
Автор: GoldFinch 9.12.2008, 19:35 |
Kallikanzarid, осталось время измерять не +-10% какбэ clock() вызывает GetSystemTimeAsFileTime, а это очень плохой метод измерения, да и увеличивать время измерения увеличивая время работы тестируемого алгоритма не самый лучший подход кстати, что это у тя прога весит 275кб и требует несистемную дллку msvcrt.dll? а зачем у тя в архиве дллка mingwm10.dll, для весу? ЗЫ: между прочим, мы начинали разговор именно о MSVC |
Автор: Kallikanzarid 9.12.2008, 19:58 | ||||||||||
J0ker, у него один проц, скажет, что ничего не заметил ![]() GoldFinch,
Пошли отговорки? ;-) Прога вести 275 кб, потому что использует статический билд libc++. msvcrt.dll есть в каждом дистрибутиве Windows, это реализация рантайма С. Если подумать, использование в качестве бэкэнда для libc++ родной для каждой платформы реализации C runtime - логичный ход со стороны GNU.
ХЗ, но билд ее требует.
Нет уж, теперь ты не отвертишься ![]()
В интересах науки заменил clock() на GetTickCount(). Результат практически не изменился. Архив прилагается.
Почему? Тут меняется только число итераций. С тем же успехом можно взять компактный алгоритм, прогнать его несколько тысяч раз и взять среднее арифметическое время. На протяжении почти всех итераций код и данные будут в кэше, и это может сказаться, но для сравнения эффективности кода той или иной реализации это не так важно. |
Автор: GoldFinch 9.12.2008, 20:12 |
Kallikanzarid, у меня код 2кб, в 137 раз меньше, если слить секции в 1 - будет весить 1кб, в 275 раз меньше если я говорил что у MSVC кодогенератор гуан* то зачем выкладывать код сгенереный gcc? и GetTickCount() тоже плохая идея, я его юзал только чтобы получать результат в секундах, мерить производительность лучше rdtsc мерять лучше так - сделать небольшую длительность 1 измерения (в идеале меньше 1 кванта времени), выполнить Sleep чтобы измерение началось в начале кванта, замерить, выполнить Sleep, замерить и т.д., а все замеры просуммировать |
Автор: Kallikanzarid 9.12.2008, 20:19 | ||||||
А зачем? ИМХО, картина и так ясна.
Ты хаил портируемый код и С++ вообще. Можешь поиграться с настройками MSVC в качестве домашнего задания. Бенчмарки показывают, что его код быстрее, чем у GCC.
Допустим. И что? ![]() Предлагаю начать новый раунд эпического противостояния. На этот раз проверим работу с памятью, в частности, с массивами. Выбирай задачу ![]() |
Автор: GoldFinch 9.12.2008, 20:20 |
цитату |
Автор: J0ker 9.12.2008, 20:22 |
мыж уже вроде решили что гуан* не компилятор, а ваше понимание? ![]() |
Автор: Kallikanzarid 9.12.2008, 20:25 | ||
Цитата:
Как наиболее характерный образчик. |
Автор: GoldFinch 9.12.2008, 20:31 | ||
только в следующем же посте я уточнил что речь идет о MSVC и начал приводить примеры его кодогенерации Хочешь эпического противостояния? по размеру оптимизировать будем? |
Автор: J0ker 9.12.2008, 20:36 | ||||
вы игнорируете мой вопрос? ![]()
Kallikanzarid, соглашайтесь - придумайте задачу, использующую как можно больше функций CRT - printf например - пусть затрахается и заодно посоревнуется в оптимизации на реальных программах ![]() |
Автор: Kallikanzarid 9.12.2008, 20:36 |
Оптимизируем по времени выполнения. |
Автор: GoldFinch 9.12.2008, 20:43 |
Kallikanzarid, а что не по размеру? Там в компиляторе даже опция есть, "оптимизировать по размеру", в MSVC по крайней мере |
Автор: J0ker 9.12.2008, 20:46 |
GoldFinch, передергиваете, да? ![]() ![]() |
Автор: Kallikanzarid 9.12.2008, 20:50 |
GoldFinch, по той простой причине, что все ЯВУ постоянно держат в памяти собственный рантайм, так что тут им конкурировать с лишенным оного ассемблером бессмысленно. Тем более, что размер экзешника в наши дни не особенно важен, тем более, если счет идет на килобайты. |
Автор: J0ker 9.12.2008, 20:51 |
Kallikanzarid, можете соглашаться - существуют специальные ужатые версии CRT - http://www.microsoft.com/msj/archive/S569.aspx |
Автор: GoldFinch 9.12.2008, 20:52 |
J0ker, ну у вас-то они уже давно закончились |
Автор: Kallikanzarid 9.12.2008, 20:54 |
J0ker, да ну, зачем мне такие извращения? У меня 1 гиг памяти, полгига видеопамяти, 2 мега кэш второго уровня, 150 гигов дискового пространства и безлимитный интернет на 1 мегабит - а я буду бороться с лишними килобайтами экзешника? |
Автор: GoldFinch 9.12.2008, 20:55 | ||
Kallikanzarid, это смотря в какой сфере объем не критичен, кое где четверть метра это очень много Добавлено через 55 секунд
поменьше бы таких программистов... |
Автор: J0ker 9.12.2008, 20:56 | ||||
так я предлагаю взять и задачу посложнее - чтоб функций из CRT было побольше задействовано чел же не понимает, что как только понадобится использовать что-то посложней - то придется либо самому все ручками писать (пусть затрахается), либо подключать ту-же CRT - а результат по размеру буде стремиться к общему - может тогда въедет, что такое мазохизм ![]() Добавлено через 1 минуту и 44 секунды
а, простите мое любопытство, ГДЕ? |
Автор: Kallikanzarid 9.12.2008, 21:02 | ||||
Не, это уже ниже пояса. Лучше взять вычислительную задачу, но с использованием массивов. А то предыдущая не дала развернуться раскрутке циклов и автоматической векторизации :-( Добавлено через 1 минуту и 51 секунду
Как сказать. Я хотел плакать, когда узнал, как разработчики ОС Minuet гордятся своим TCP-стеком. Именно тем фактом, что им удалось сделать TCP-стек. На ассемблере. |
Автор: GoldFinch 9.12.2008, 21:16 |
J0ker, вы когданить видели например графическую ОС которая влезает на дискету? Kallikanzarid, а ты сделал свой TCP-стек чтобы так говорить? Или знаеш как его сделать? |
Автор: Kallikanzarid 9.12.2008, 21:22 | ||
1) Я уже давно не видел ни одной дискеты. 2) Нет. Меня этот вопрос не интересовал. Однако я знаю, что в никсах эти стеки были, еще когда меня на свете не было. ЗЫ: так новый раунд будет? Ты уже выбрал задачу? |
Автор: J0ker 9.12.2008, 21:23 | ||||
а зачем? у меня и флоповода-то нету ![]() зато есть стааааарый флеш-драйв купленный лет 5-6 назад размером 512 метров ![]() и, если мне не изменяет память, размер даже 5-ти дюймового диска был 360кБ в пору моей молодости (извините, перфокарты зацепил только чуть-чуть) - так размер CRT все равно меньше значительно, а всю функциональность иначе вам придется ручками писать и вы все равно придете к тому-же размеру ![]() Добавлено через 1 минуту и 57 секунд
я не писал но знаю как не вижу здесь никакого геройства кроме гемороя задача-то тривиальная, все стандарты есть |
Автор: Mayk 10.12.2008, 08:25 | ||
клйовый тред, в избранное! Действительно кому нужны программеры которые вместо того чтобы писать 2 часа на асме будут писать пять минут на си?
Ну я видел MenuetOS. Не знаю что с ним еще можно сделать кроме как "увидеть". |
Автор: GoldFinch 10.12.2008, 13:07 |
близкую к реальной задачу значит... допустим так... надо разработать программу для генерации SFX архивов, размер распаковщика определяется следующими требованиями: архивы хранятся в библиотеке архивов на хостинге с максимально доступным дисковым пространством 100Мб, файлов примерно 500-550, размер 1 файла в диапазоне от 10 до 350кБ, распаковщик должен быть не более 20% от размера файла целевая ОС - 32разрядная WinXP, т.к. задача тестовая - никакой реальной упаковки не требуется, при запуске распаковщик извлекает файл в указанную пользователем папку. |
Автор: Kallikanzarid 10.12.2008, 14:06 |
Что, на производительность асма ты забил? Зачем опять гнешь свои 2кб? Блин, будь мужчиной уже ![]() |
Автор: GoldFinch 10.12.2008, 15:01 |
Kallikanzarid, так или иначе, каким бы производительным твой код не был, я всегда могу извлечь код из твоего бинарника, оптимизировть и засунуть в свой. Там всегда будет что оптимизировать, и я хз о каком соревновании тут может идти речь. |
Автор: Kallikanzarid 10.12.2008, 15:06 |
Слив засчитан ![]() |
Автор: Mayk 10.12.2008, 15:21 | ||
это равносильно заявлению "компилятор пишет асмовский код лучше чем я" кстати |
Автор: mes 10.12.2008, 15:44 | ||
Да неблагодарное это дело, сравнивать языки без ориентировки на определенную задачу. Так же как например взять русский и английский. Имхо, у русского больше форм и возможностей выражения - но это его преимущество является недостатком, при техническом применение. Английский же в данном аспекте более удобен. Также cpp, c, asm разняться от абстрактности мысли к ее точному применению. Да на асме можно заточить алгоритм под конкретную архитектуру .. решенная эта же задача на си будет переносима, а на cpp к тому же даст гарантию проверки типов. Т.е отдаляясь от точности разъяснения алгоритма конкретной машины, мы приходим к тому что машина (компилятор) сама подгоняет и контролирует код, а результативный код удовлетворяет выдвинутым задачей требованиям (в одних случаях критичен размер, в других скорость, в третьих безопасность кода и длительная поддержа и расширение) Тесты показывают что c/cpp не отстает от асма по скорости. Да по размеру бинарника асм выигрывает, зато проигрывает в ых сферах с человеческим фактором.. Ну а скорость и размер для "потребительских" задач уже давно перестали быть решающим требованиями.. Я считаю что максимальный эффект можно добиться если правильно подобрать инструмент/ы к текущей задаче (прокопать тунель под Ла-Маншем лопатой конечно геройство, но задача трудновыполнимая и не имеющая смысла), но также не надо забывать, что языки всего лишь инструмент, и основное зависит от того насколько им хорошо умеет пользоваться программист е |
Автор: Kallikanzarid 10.12.2008, 15:47 |
mes, тссс! Не порть знатный срачег. |
Автор: GoldFinch 10.12.2008, 16:37 | ||
ага, так или иначе, подобное сравнение упирается не в сравнение производительности программы вручную написанной на асме против производительности программы написанной на ЯВУ, а в мастерство одно и другого программиста. в конце концов компилятор ЯВУ - инструмент и ничто не мешает взять автоматически сгенерированный им код и вручную доработать его до идеала. |
Автор: mes 10.12.2008, 17:10 | ||||
такой способ (если конечно ручная доводка необходимa) также присутствует в данной цитате :
![]() |
Автор: GoldFinch 10.12.2008, 17:17 | ||
а всетаки
программирование на асме ничуть не медленнее программирования на С++,
даже быстрее с учетом времени создания нового проекта и компиляции.
опять же на .ехешку в 1кб смотреть приятно
|
Автор: J0ker 10.12.2008, 17:19 | ||
тесты показывают, что как только задача сталкивается с реальностью многоядерного процессора, то только гений может оптимизировать код лучше компилятора Добавлено через 1 минуту и 24 секунды
мешает, мешает см. выше |
Автор: GoldFinch 10.12.2008, 17:23 |
J0ker, здравый смысл подсказывает что кодогенератор твоего компилятора тоже люди писали, написать менее универсальный но более эффективный не проблема |
Автор: mes 10.12.2008, 17:23 | ||
если программа для решения мелкой задачи то трудно оценить.. А вот например составить браузер или тот же самый компилятор ? думаю мало кто из программистов отважится затеять такой проект на асме , хотя "герои" безусловно есть ) |
Автор: J0ker 10.12.2008, 17:24 | ||
издеваешься, да? ![]() |
Автор: mes 10.12.2008, 17:28 |
Да существует куча компиляторов, некоторые заточны под универсальность, другие под конкретную архитектуру и можно выбрать тот, который больше подходит ![]() |
Автор: J0ker 10.12.2008, 17:30 | ||
только не в пример нам лучше знающие особенности процессоров - это во-первых во-вторых, логика распараллеливания настолько сложна, что даже люди из во-первых не в состоянии оптимизировать более-менее сложный код - они для этого написали умную программу, которая это делает - она называется компилятор Добавлено через 1 минуту и 18 секунд с первым согласен со вторым нет - для более-менее сложного кода - см.выше Добавлено через 9 минут и 18 секунд я много раз сталкивался с подобными спорами и если лет 10 назад еще можно было показать, что программа, написанная на ассемблере более производительна, то как только появились многоядерные процессоры, это стало практически невозможно - разборы полетов показали, что компилятор может раскидать инструкции так, что они хорошо параллелятся - при этом логика оказывается настолько сложна, что ни один человек не в состоянии такое написать, а якобы бессмысленные с т.з. человека операции (например замена одного оператора парой других, выполняющихся заведомо медленней) приводит к повышению производительности - что обусловлено опять-таки распараллеливанием |
Автор: Kallikanzarid 10.12.2008, 17:47 | ||
Ты имел ввиду конвеерные суперскалярные процессоры? А то применительно к мультиядерности ты написал хню ![]() |
Автор: J0ker 10.12.2008, 19:50 | ||
о мля, точно, переклинило ![]() |
Автор: GoldFinch 10.12.2008, 20:10 |
J0ker, береш
справочник Агнера Фога, и пишешь код не хуже того что генерит
компилятор. Компилятор хорош тем что избавляет от рутины за счет
неидеальной кодогенерации и отсутствия средств управления кодогенерацией Может там и будет офигенное распараллеливание, но вот идиотские неоптимальности типа push reg32 / fld dword [m32real] / fstp dword [esp] вместо push dword [m32real] всеравно останутся |
Автор: Kallikanzarid 10.12.2008, 20:15 |
GoldFinch, пользуясь случаем, еще раз предлагаю тебе второй раунд. Докажи, что асм-код для FP или целочисленных вычислительных методов и правда выполняется быстрее компилируемого. Все, что тебе нужно сделать - это выбрать адекватный алгоритм и написать ее реализацию, которая работала бы быстрее моей на С++. |
Автор: GoldFinch 10.12.2008, 20:34 |
Kallikanzarid, выложи свой бинарник я его оптимизирую и "мой" код будет работать быстрее. Если говорить о сравнении различных реализаций, то все упрется в то чье программерское мастерство лучше, так я и на С++ напишу код быстрее твоего ^^ |
Автор: mes 10.12.2008, 20:36 |
заочно оценили ? чудеса ![]() |
Автор: GoldFinch 10.12.2008, 20:41 |
mes, ага, с доверительной вероятностью 95% |
Автор: Kallikanzarid 10.12.2008, 20:41 |
GoldFinch, нет уж - назвался груздем - полезай в кузов. Либо чисто на ассемблере - ты ведь его сторонник - либо чисто на С++. Во втором случае, ясное дело, будут беспристрастные судьи, которые будут получать исходники и батники, запускающие компилятор, и выдавать результаты; исходники друг от друга будем хранить в тайне. В любом случае, я уже сутки жду от тебя задачу. |
Автор: GoldFinch 10.12.2008, 21:14 |
Kallikanzarid, так мы что тестировать будем? "С++ vs асм" или "Kallikanzarid vs GoldFinch"? |
Автор: Kallikanzarid 10.12.2008, 21:16 |
Давай второе. |
Автор: GoldFinch 10.12.2008, 21:39 |
я тоже суп както не очень. вобщем я завтра вечером те тестовый алгоритм и методику измерения напишу десятая страничка однако.... |
Автор: J0ker 10.12.2008, 22:13 | ||||||
yуууу "береш справочник по шахматам и обыгрываеш Каспарова" ![]()
я вам уже показал, что "неидеальность" обычно вызвана непониманием - вы упорно игнорируете этот факт ![]()
упрямство - достоинство сами знаете кого ![]() я вам знаете что советую напишите-ка на ассемблере вычислительный модуль BIONIC'а и запустите - а мы посмотрим, примет ли сервер ваши "оптимизированные" вычисления ![]() |
Автор: GoldFinch 11.12.2008, 21:13 | ||
Kallikanzarid,
вобщем я подумал-подумал, даже на форуме поспрашивал на каком алгоритме
может загнуться С++ в отличие от асма, да только подходящего ответа не
получил, да и сам ничего толкового не придумал... Что попроще и 100%
сработает - неинтересно, а то что сложно - самому долго
писать. Пришлось придумать нормальную задачу, близкую к реальной. Нужно написать функцию bool __stdcall Tick(float x); Функция принимает на вход некореллированную последовательность равномерно распределенных вещественных чисел Xi, 0<=Xi<A<=1 Для i от 0 до N-1 параметр распределения A равен 1, для чисел с i от N до 2*N-1 параметр распределения A равен 0.5 Функция должна возвращать 1 при i<N+D и 0 при i>=N+D, где D - задержка срабатывания функции. Производительность функции оценивается произведением времени работы функции T за одну итерацию на задержку срабатывания функции D, либо суммой времени выполнения D итераций, это значение должно быть минимально. Допускается не более 5% ложных срабатываний (возврата 0 при i<N), причем N>100, первые 100 тактов ложные срабатывания не считаются. Код функции следует оформить в виде DLL и сделать эту функцию экспортируемой, имя не важно, импортировать будем по ординалу. В DllMain() можно инициализировать переменные, выделить память и проч. Программа тестирования, одна и та же для всех длл, будет загружать длл, вызывать эту функцию и замерять ее время исполнения. Примерный код программы тестирования:
Размер бинарника, используемой виртуальной памяти неограничен, но будем считать что прога будет работать на компе с 512-1Гб ОЗУ Что-то может следует откорректировать, чтото уточнить, в целом думаю задача получилась неплохая =) |
Автор: Kallikanzarid 11.12.2008, 21:50 |
Уточни парочку моментов: 1) Речь идет о нормальном распределении случайных чисел? 2) Что именно должна делать функция? Как я понимаю, ее выходное значение зависит от того, какой по счету раз ее вызвали и совершенно не зависит от передаваемого аргумента? Или я неправильно понял? 3) Как функция получит значение N? |
Автор: GoldFinch 11.12.2008, 22:22 | ||||
1) о равномерном, но можно сделать и нормальным.
2) функция должна определить что параметры входной последовательности изменились и вместо 1 вернуть 0 например она должна вычислять матожидание или дисперсию фактически ее выходное значение должно както зависеть от предидущих значений Как именно зависеть - решать тебе. Чтобы хранить эти значения можно использовать глобальные переменные, массивы, буферы, что захочешь. 3) N и i ей знать не надо, только принимать входные числа Xi, както накапливать их и возвращать Выглядит это так
|
Автор: J0ker 11.12.2008, 22:31 |
что-то мне мнится, что производительность в данной задаче будет упираться в алгоритм, а не в то, на чем он написан ![]() |
Автор: GoldFinch 11.12.2008, 22:33 |
J0ker, ну Kallikanzarid же сказал что ему интереснее "Kallikanzarid vs GoldFinch" чем "С++ vs асм"... |
Автор: J0ker 11.12.2008, 22:56 |
ну в таком случае мне
не ясно, зачем вы нивелировали задачу 5-ю процентами - ИМХО скорость и
качество определения параметра распределения должны входить в оценку
результата умственного онанизма оппонентов ![]() |
Автор: GoldFinch 11.12.2008, 23:00 |
J0ker, а как тогда оценку рассчитывать? тем более что если не задавать Pлс, то возможно будут решения с максимальным быстродействием и принципом "угадал\неугадал" |
Автор: J0ker 11.12.2008, 23:06 | ||
ну так об этом надо и договариваться
да, но качество тогда снизится вдвое, при этом в формуле должна участвовать задержка D - в этом случае такой алгоритм станет заведомо проигрышным |
Автор: GoldFinch 11.12.2008, 23:19 |
J0ker, проще задать вероятность не менее 95% чем выдумывать сомнительные интегральные критерии |
Автор: Kallikanzarid 12.12.2008, 07:30 |
GoldFinch, лучше взять нормальное распределение. И использовать не самодельную эвристику, а boost::random. А вообще задача очень интересная ![]() |
Автор: GoldFinch 12.12.2008, 08:59 |
Kallikanzarid, ок, а какие матожидания и дисперсии? и по какому алгоритму нормальное распределение получать будем? |
Автор: Kallikanzarid 12.12.2008, 12:29 |
Предлагаю матожидание - 0.70 и 0.25, а дисперсию - 0.3 и 0.15. Для гененрации предлагаю взять хорошо известную библиотеку boost::random - http://www.boost.org/doc/libs/1_37_0/libs/random/index.html |
Автор: GoldFinch 12.12.2008, 20:18 | ||
мм.... а почему именно такие числа? выглядит это несколько неудобно: http://spreadsheets.google.com/pub?key=pneb3GWHrZ5iTmapONJT2ew&oid=1&output=image впрочем, чтобы и нет... мне библиотека boost::random, но если она действительно удобная, можно и ее применить вот еще какое предложение... если учитывать что число итараций (N) до момента изменения параметров распределения мало, то возникает соблазн сделать в программе буфер чисел этак на 10000000 и писать всю входную последовательность в него, не заботясь о том что буфер может закончиться. Вот чтобы такого небыло, предлагаю считать N значительно большим размера любого буфера. |
Автор: Kallikanzarid 12.12.2008, 20:37 |
boost::random можешь
оценить сам - по ссылке есть туториал. А матожидания и дисперсии лучше
и правда сделать подальше друг от друга ![]() Добавлено через 2 минуты и 53 секунды Насчет N согласен, давай и правда сделаем его достаточно большим. |
Автор: Ln78 12.12.2008, 20:48 | ||||
Давно на форум не заходил, тут такие бойкие новички появились. GoldFinch, а почему ты сам задачу ставишь? Это всё равно, как если бы, например, я предложил тебе такой вариант: давай я загадаю число, а потом с тобой посоревнуемся, кто его отгадает за меньшее число попыток. ![]() |
Автор: Kallikanzarid 12.12.2008, 21:11 |
Ln78, если что, еще один раунд проведем. А вот судья, который будет принимать длл-ки и говорить результаты, нам не помешает. |
Автор: J0ker 12.12.2008, 21:12 | ||
не, спасибо у меня нет специального математического образования ![]()
какой в этом смысл, если допустимая задержка 5% предлагаю сделать расширяемый буфер, равный 10% от текущего i - ИМХО единственное логичное решение - распределение-то заранее известно |
Автор: Kallikanzarid 12.12.2008, 21:13 |
GoldFinch, предлагаю также встроить в тестирующую программу опциональный индикатор прогресса. |
Автор: GoldFinch 12.12.2008, 21:14 |
Ln78, а я вообще на этот форум не заходил, а тут зашел - а тут вот как интересно)))) Kallikanzarid сам попросил чтобы я поставил задачу, я ее и поставил. Впринципе я не против того чтобы задачу ставила 3я сторона, если конечно задача будет интересная. К слову для меня эта задача достаточно сложная, т.к. я уже успел благополучно забыть статистику (если было что забывать %)) Kallikanzarid, да не вопрос, можно еще сразу сделать 100 запусков алгорима, циклом: for(int nTests=0; nTests<100; nTests++) { hDll=LoadLibrary("showdown.dll"); ... //i-й тест FreeLibrary(hDll); }; |