3

1) У меня есть много констант в моем C algo. 2) мой код работает как с плавающей точкой, так и с фиксированной точкой.инициализировать переменную статически (во время компиляции)

Прямо сейчас эти константы инициализируются функцией float2fixed, в результате чего в плавающей точке она ничего не делает, а в фиксированной точке находит свое фиксированное представление. Например, 0.5f остается 0.5f, если работает в плавающей точке, тогда как использует процедуру pow() и становится 32768, если работает в фиксированной точке, а представление с фиксированной точкой - Qx.16.

Это легко поддерживать, но для вычисления этих констант в фиксированной точке требуется много времени (pow - функция с плавающей точкой). В C++ я бы использовал некоторое метапрограммирование, поэтому компилятор вычисляет эти значения во время компиляции, поэтому во время выполнения нет никакого удара. Но в C это невозможно. Или это? Кто-нибудь знает такую ​​уловку? Является ли какой-либо компилятор достаточно умным для этого?

С нетерпением жду любых ответов.

+0

Почему вы не можете использовать C++? – Zifre

+0

C не поддерживает макропроцессоры препроцессора? – CookieOfFortune

+0

@CookieOfFortune: макросы не так сильны, как C++-шаблоны (они даже не завершены Turing), но это возможно. – Zifre

ответ

0

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

Некоторые опции я могу думать:

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

  2. Как уже упоминалось в другом комментарии, используйте метапрограммирование шаблона в любом случае и скомпилируйте его с помощью компилятора C++. Большинство C отлично работают (возможно, лучше) с компилятором C++.

Хм, я думаю, это все, о чем я могу думать. Удачи.

2

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

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


Я имею в виду написать простую программу, которая может сканировать для формульных линий, которые могли бы читать:

const double somename = 3.14159; 

было бы прочитать, что и генерировать:

const fixedpoint_t somename = { ...whatever is needed... }; 

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

datafile.c: datafile.constants converter 
     converter datafile.constants > datafile.c 
+0

тоже хлопотно. Я должен разработать для 6 платформ уже, и это начало. – vectorizor

+1

Итак, используйте для этого общий код - наверняка, материал с фиксированной точкой постоянно на разных платформах, во всяком случае? В любом случае, если это слишком сложно сделать во время компиляции, вам, вероятно, придется взять удар во время выполнения. Удачи. (6 платформ не так уж плохи - это обычное дело, где я работаю), и я рассчитываю на Linux на IA32, IA64, Itanium, zLinux, PPC как на одну платформу, а не на пять.) –

+0

ну, не играть, у кого есть самый большой: D, но мне нужно запускать на ARM, x86, графические процессоры ... т.е. значительно и больно, разные процессоры. Я побеждаю? :) – vectorizor

4

Вместо того чтобы использовать (unsigned)(x*pow(2,16)), чтобы сделать ваши преобразования неподвижной точки, записываются как (unsigned)(0.5f * (1 << 16))

Это должно быть приемлемым в качестве постоянного выражения во время компиляции, так как она включает в себя только встроенные оператор.

+0

очень хорошая идея! – vectorizor

1

Последние версии GCC (около 4.3) добавили возможность использовать GMP и MPFR для оптимизации времени компиляции путем оценки более сложных функций, которые являются постоянными. Этот подход оставляет ваш код простым и портативным, и доверяйте компилятору выполнять тяжелую работу.

Конечно, существуют ограничения на то, что он может сделать, и было бы трудно узнать, не оптимизирует ли данный экземпляр, не идя на сборку. Но, возможно, стоит проверить. Here's a link to the description in the changelog

+0

Но он был бы переносимым только до того момента, когда компилятор, который вы переносите, поддерживает одни и те же оптимизации. В противном случае он может компилироваться для другой платформы, но производительность выполнения может быть неприемлемой. Представьте, что вы портируете что-то подобное встроенной системе с компилятором, который не поддерживает расширенные оптимизации GCC. – VoidPointer