|
ru.linux- RU.LINUX --------------------------------------------------------------------- From : U.P.Galyuck 2:5020/400 23 Mar 2005 20:07:40 To : Ilya Anfimov Subject : Re: Need GUI development tool (Kylix or something) -------------------------------------------------------------------------------- > >> В GNU C комплексная арифметика есть. > > > > Расскажи, пожалуйста, в какой версии С-компилятора комплексная > > арифметика присутствует, какие ключевые слова при этом используются, и по > > какому стандарту это реализовано. Без этих пояснений отвечать на остальные > > man 5 complex, далее по ссылкам, включая C99. > Или info libc /complex (откуда я впервые про это узнал). > Тогда, когда я этим пользовался, был, кажется, gcc 2.7.2.1 > Впрочем, это я мог и запамятовать, и там уже был 2.9x, x < 5. Спасибо, я, действительно, обнаружил у себя (gcc 3.2.2) эту так сказать комплексную арифметику. Hет, не зря я не знал о ее существовании. Это типичный образец того, как формально решая поставленную задачу (введение нового типа complex) по существу получается издевательство (В.И.Ленин). Вся проблема реализации этого типа данных оказывается именно в том, что реализация этой арифметики оказывается для компилятора чем-то внешним, навешанным снаружи через макросы. В силу этого, компилятору очень трудно провести оптимизацию кода, а именно: операции с операндами разного типа данных. Сразу приходящее в голову решение привело к тому, что при перемножении комплексного и вещественного числа происходит сначала приведение более простого типа (float) к комплексному (копированием вещественной переменной в реальную часть структуры и копированием нулевой константы в мнимую часть), после чего происходит перемножение переменных по правилу комплексная на комплексную. Итак - вместо двух перемножений, которые требуются по алгоритму, получается 4 умножения и два сложения. Еще хуже ситуация, когда программируется выражение вида a*b*z, где a, b - типа float, а z - complex. Сначала вычисляется b*z, и т.к. они разных типов, происходит приведение вещественного b к комплексому типу с перемножением общего вида, после чего уже переменная a приводится к комплексному типу и снова перемножаются комплексные операнды. Итого - вместо 3-х умножений было потрачено 12 умножений и 4 сложения, не считая затраты на приведения (пересылки), которые в современных процессорах занимают такое же время, как и арифметические операции. Замечу, что усли записать выражение в виде z*b*a, т.е. вещественные операнды после комплексного, то оно делается за 5 умножений и 4 сложения, что тоже далеко от идеального с 3-мя умножениями. Оптимизация (-О3) никак не изменила количества операций. Все это происходит потому, что компилятор ничего не знает о свойствах этого типа данных (коммутативности и ассоциативности) и не может так переставить операции, чтобы сначала делалась вещественная арифметика, а потом комплексная, да еще учитывалась перегруженность операций с разными сочетаниями типов. В Фортране, для которого комплексный тип является встроенным, это делается достаточно просто. В С, и как я подозреваю в С++ , это либо не делается вообще (главное, чтобы формально поддерживался этот тип данных), либо очень трудно реализовать. Поэтому научные программы еще долго будут разрабатываться на специально для этого приспособленном языке - Фортран, а все логические умозаключения, основанные на собственном понимании проблемы, и "принципе Оккама", оказываются опровергнутыми элементарными тестами (все, что я описал, я выяснил, вычитывая ассемблерный листинг результатов компиляции). Галюк Юрий --- ifmail v.2.15dev5.3 * Origin: St.Petersburg University (2:5020/400) Вернуться к списку тем, сортированных по: возрастание даты уменьшение даты тема автор Архивное /ru.linux/6578716ac6ae.html, оценка из 5, голосов 10
|