Y_Mur Согласен, всопнил аналогичные ситуации, с обработкой массива данных и хранением констант на стэке для этой самой обработи одновременно. А линк интересный, только вот всё-равно не ясно что удобнее при обработке массива - перемешивать операции загрузки из памяти с самой обработкой или же использовать некое подобие "burst read" в стэк сопроцессора с долгой обработкой этих самых загруженных данных.
Вот про это я и говорю, что алгоритм неоптимальный. Не надо путать алгоритм и его реализацию. Чем правильней алгоритм, тем меньше ресурсов он требует для реализации. А если ресурсов для реализации (например, тех же регистров) не хватает, или их требуется много - значит что-то неправильно ... Такова моя нескромная имха
Y_Mur Ну да, что-то похожее. Рассматривается некая аналогия с simd операциям. Лучше сначала нагрузит чтение в регистры фпу а потом однотипная обработка каждого значения в регистрах или лучше чередовать обработку/чтение ну и соответственно запись в конце всего? Т.е. кусочные чтение/запись против монолитного/последовательного.
cresta Не правильная скромная имха Если есть массив с данными, по которым нужно пробежаться достаточно навороченной функцией, сохранить результат вычислений для дальнейшего использования и корме того разделить его на х, у составляющие которые затем смасштабировать (масштабные множители по х, у разные) и поместить в массив координат для представления в виде графика, то конечно можно решить эту задачу в много проходов, каждый раз задействуя всего по 2-3 регистра, но это как раз и не оптимально, поскольку потребует множества лишних обращений к памяти
asmfan У меня такого выбора нет поскольку задача обрабатывать массивы и считать численные интегралы, поэтому сначала гружу во все свободные от промежуточных результатов (типа накапливающейся суммы для численного интеграла и временных переменных для промежуточных вычилений) константы нужные для функции обработчика, а затем бегу по массиву по принципу взял-обработал-сохранил-взял следующий элемент.
Y_Mur Ну если даже один элемент стэка остаётся пустым, то такой выбор уже появляется. И вопрос становится актуальный.
В той литературе, что есть у меня нет понятного объяснения работы сопроцессора. Что именно делают команды fincstp & fdecstp и нафига это надо. Если можно то покажите на примере.
Hotwire Во-первых, не очень "тормознуто", т.к. на современных компах FXCH реализуется на уровне переименования регистров, т.е. обмен регистров производится логически, а не физически. Поэтому FXCH, также как и NOP, независимая инструкция, которая может выполниться вне очереди в любой подходящий момент Во-вторых, при правильном планировании порядка загрузки и размещения операндов, использовании операций st(i),st(0)\st(0),st(i)\st(0),mem и обратных операций типа fsubr\fdivr использование fxch можно свести к минимуму
Могу дать немножко доки по FPU, если мыло дашь. Неужели аттачь прицепился, фантастика. Только смотри там где про FPU, остального нет, большой размер вышел бы.
это не текст, а код загрузится в st0. Не мучайся, возьми OllyDbg (отладчик) и смотри в нем, что делает код. Там все отображается: и регистры, и стек, и флаги, как для основного процессора, так и для fpu. Выполняешь в пошаговом режиме и смотришь, что происходит с регистрами после каждой инструкции.
Hotwire Никуда, т.к. это конструкция бессмысленная и при загрузке операнда из памяти приводит к ошибке переполнения стека FPU 1) fincstp инкрементирует указатель стека, в результате чего st1 становится st0, а st0 -> st7, но в отличие от fstp st0 регистр st7 не помечается как свободный, а остается занятым. 2) fld src сначала делает декремент стека, т.е st0 переходит в st1, а st7 в st0, и затем уже грузит значение в новый st0, но если перед загрузкой он оказывается помечен как занятый, то происходит ошибка - переполнение Вывод: 1) использовать сочетание fincstp+fld нельзя, можно только fincstp+fadd и т.п. 2) в старых процах (PMMX и ниже) fxch работала медленнее fincstp\fdecstp, т.к. производила реальный обмен содержимого регистров, но в современных процах fxch и fincstp\fdecstp по скорости эквивалентны, т.к. они работают на уровне переименования регистров в RAT и не задерживают следующие за ними инструкции. Поэтому полезность использования fincstp\fdecstp вместо fxch в современных процах вообще сомнительна PS: приведи пример кода, в котором у тебя получаются "лишние" fxch - посмотрим как от них можно избавиться
leo Код (Text): fincstp fld aa fld aa fadd загружает таки аа в st0. И никаких последствий. С этим значением st0 можно производить валидные операции и получать валидный результат. Т.е. в st0 будет 2*аа
cresta Шутишь ?! Если стэк FPU девственно чист, то ес-но fincstp ни на что не вляет и является бессмысленной Но ведь с твоей подачиавтор пытается ее применить с "пользой". А если st0 занят, то то при fincstp+fld получается двойная бессмысленность: 1) если бы даже исключения не было, то в любом сл.по логике вещей получается глупость - сначала fincstp смещает st0 в st7, а затем fld смещает st7 в st0 для того чтобы затереть его новым значением 2) но исключение все-таки генерится при любом fld и в st0 грузится -NAN, что легко проверить в Оле. Но если исключения FPU замаскированы (по умолчанию ), то это приводит только к неверному результату. Ну а если не замаскированы, то на следующей fpu-инструкции происходит сам понимаешь что )
leo Не надо путать. Я просто сказал, что существуют инструкции fincstp и fdecstp и объяснил, что они делают. А то что автор поставил эти инструкции в начале кода, а потом грузит регистр - то не моя вина. То что с ходу выполняется fincstp - это ясно что глупость (все регистры empty). Но мы не знаем, есть ли перед этим какой-то код или нет. Так что формально этот код грузит значение в st0, несмотря на бессмысленность в данном контексте инструкции fincstp. И исключений этот код никаких не генерит. Смотри Олю Я уже смотрел, поэтому и утверждаю: никаких исключений нет. В том числе и на последующих инструкциях (если они корректны естественно).
cresta Я тоже смотрел и поэтому утверждаю: если перед fincstp регистр st0 занят, то исключение есть Код (Text): finit ;st0 empty, st7 empty fld1 ;st0 valid = 1.0 st7 empty fincstp ;st0 empty, st7 valid = 1.0 fldpi ;st0 bad = -NAN, st7 empty, Err S=1, I=1 !!! ИСКЛЮЧЕНИЕ fwait PS: Если хочется отправить отчет в Microsoft, то достаточно размаскировать исключение Invalid Operation, вставив после finit три инструкции: fstcw [cw] + and [cw],0FEh + fldcw [cw]