Перейти к содержанию
    

Degun

Участник
  • Постов

    84
  • Зарегистрирован

  • Посещение

Репутация

0 Обычный

Информация о Degun

  • Звание
    Частый гость
    Частый гость

Контакты

  • Сайт
    Array

Информация

  • Город
    Array
  1. С typedef-ом следующая история. Если сделать так: template <typename DataT> class TTreeObj { private: TTreeObj<DataT>* parent; list<TTreeObj<DataT>*> *childs; public: TTreeObj(DataT d=0, TTreeObj<DataT>* p=NULL) : info(d), parent(p), childs(NULL) {} DataT info; ..... }; typedef TTreeObj<DataT> TreeObjRefT; template <typename DataT> TTreeObj<DataT>* TTreeObj<DataT>::operator[](int Index) { ...... list<TreeObjRefT*>::iterator iterator_begin=childs->begin(); ..... return *iterator_begin; } то выводит такое сообщение об ошибке: "ap_common.h", line 817: error: identifier "DataT" is undefined Если сделать так: template <typename DataT> class TTreeObj { private: TTreeObj<DataT>* parent; list<TTreeObj<DataT>*> *childs; public: TTreeObj(DataT d=0, TTreeObj<DataT>* p=NULL) : info(d), parent(p), childs(NULL) {} DataT info; ..... typedef TTreeObj<DataT> TreeObjRefT; }; template <typename DataT> TTreeObj<DataT>* TTreeObj<DataT>::operator[](int Index) { ...... list<TreeObjRefT*>::iterator iterator_begin=childs->begin(); ..... return *iterator_begin; } то выводит такое сообщение об ошибке: "ap_common.h", line 827: error: identifier "iterator_begin" is undefined Как правильно нужно сделать?
  2. Для следующей строки, использующей контейнер list из STL и шаблоны, list< TTreeObj<DataT>* >::iterator iterator_begin=childs->begin(); в Code Composer Studio выдаётся такое сообщение об ошибке: "ap_common.h", line 851: error: expected a ";" Т. е. компилятору не нравится конструкция list< TTreeObj<DataT>* > Таже самая строка в Microsoft Visual Studio 2008 компилируется без проблем. Как это исправить?
  3. Я думаю здесь все в курсе того, что формат с фиксированной запятой является всего лишь приближенным представлением действительного числа. Подробнее об этом можно прочитать, например, по ссылке ниже: http://matlab.exponenta.ru/fixedpoint/book1/1.php
  4. Да, т. е. для хранения целой и дробной частей числа отводятся разные биты одной и той же переменной длиной 64 бит.
  5. А вы посмотрите по ссылкам: там плавающее число хранится в одной целочисленной переменной и запятая смещена относительно начала регистра на определённое кол-во бит.
  6. Сейчас как раз думаю над этим вариантом. Возникает вопрос о его целесообразности, т. к. есть более простые и быстрые, но, соответственно, менее точные варианты реализации плавающей арифметики: http://www.koders.com/cpp/fid5E90955711BFB...1C652C383C.aspx http://electronix.ru/forum/index.php?showt...45865&st=26 Вообще же эти варианты работают значительно быстрее, чем эмуляция плавающей арифметики через компилятор. Для предлагаемого вами варианта необходима будет операция по суммированию двух чисел с учётом флага переноса, которой в C++ нет.
  7. Как-то это некрасиво - лучше пойти другим путём. Я сделал класс на основе представления плавающего числа типа double в виде целочисленного типа long long (на основе класса fastfloat по ссылке http://www.koders.com/cpp/fid5E90955711BFB...1C652C383C.aspx). Такой подход предоставляет полный эквивалент числа с плавающей запятой без использования последнего. Моя тестовая функция билинейного масштабирования при этом сразу стала выполняться в полтора раза быстрее. И это при том, что я её ещё не оптимизировал насчёт применения DMA (тогда бы улучшение производительности было бы гораздо заметнее). Так что предлагаю к использованию (охотно принимаются замечания по улучшению производительности этого класса или замеченные ошибки). /*!\file fastfloat.h * \brief This class stores floating point numbers as integers, * \brief with BITS shift, i.e. value XYZ is stored as XYZ * RATIO * \version 1.0 * \date 25 april 2008 */ #ifndef __FAST_FLOAT_H #define __FAST_FLOAT_H class fastdouble { private: enum { BITS = 16, RATIO = 65536 }; long long value; inline fastdouble( long v, bool ) : value( v ) {} // for operator-() public: inline fastdouble() { value=0; } inline fastdouble( double v ) { value=static_cast<long long>(v * RATIO + 0.5); } inline fastdouble( float v ) { value=static_cast<long long>(v * RATIO + 0.5); } inline fastdouble( char v ) { value=static_cast<long long>(v) << BITS; } inline fastdouble( short v ) { value=static_cast<long long>(v) << BITS; } inline fastdouble( int v ) { value=static_cast<long long>(v) << BITS; } inline fastdouble( long v ) { value=static_cast<long long>(v) << BITS; } inline fastdouble( unsigned char v ) { value=static_cast<long long>(v) << BITS; } inline fastdouble( unsigned short v ) { value=static_cast<long long>(v) << BITS; } inline fastdouble( unsigned int v ) { value=static_cast<long long>(v) << BITS; } inline fastdouble( unsigned long v ) { value=static_cast<long long>(v) << BITS; } inline void operator =( fastdouble r ) { value=r.value; } inline void operator =( double v ) { value=static_cast<long long>(v * RATIO + 0.5); } inline void operator =( float v ) { value=static_cast<long long>(v * RATIO + 0.5); } inline void operator =( char v ) { value=static_cast<long long>(v) << BITS; } inline void operator =( short v ) { value=static_cast<long long>(v) << BITS; } inline void operator =( int v ) { value=static_cast<long long>(v) << BITS; } inline void operator =( long v ) { value=static_cast<long long>(v) << BITS; } inline void operator =( unsigned char v ) { value=static_cast<long long>(v) << BITS; } inline void operator =( unsigned short v ) { value=static_cast<long long>(v) << BITS; } inline void operator =( unsigned int v ) { value=static_cast<long long>(v) << BITS; } inline void operator =( unsigned long v ) { value=static_cast<long long>(v) << BITS; } inline double toDouble() const { return static_cast<double>( value ) / RATIO; } inline long toLong() const { return static_cast<long>(value >> BITS); } inline operator double() const { return toDouble(); } inline operator float() const { return (float)toDouble(); } inline operator char() const { return (char)toLong(); } inline operator short() const { return (short)toLong(); } inline operator int() const { return (int)toLong(); } inline operator long() const { return toLong(); } inline operator unsigned char() const { return (unsigned char)toLong(); } inline operator unsigned short() const { return (unsigned short)toLong(); } inline operator unsigned int() const { return (unsigned int)toLong(); } inline operator unsigned long() const { return (unsigned long)toLong(); } inline fastdouble operator - () const { return fastdouble( -value, false ); } inline fastdouble& operator += ( fastdouble r ) { value += r.value; return *this; } inline fastdouble& operator -= ( fastdouble r ) { value -= r.value; return *this; } inline fastdouble& operator *= ( fastdouble r ) { value = ( value * r.value ) >> BITS; return *this; } inline fastdouble& operator /= ( fastdouble r ) { value = ( value << BITS ) / r.value; return *this; } inline fastdouble& operator += ( double v ) { value += static_cast<long long>( v * RATIO + 0.5 ); return *this; } inline fastdouble& operator -= ( double v ) { value -= static_cast<long long>( v * RATIO + 0.5 ); return *this; } inline fastdouble& operator *= ( double v ) { value = static_cast<long long >( value * v + 0.5 ); return *this; } inline fastdouble& operator /= ( double v ) { value = static_cast<long long>( value / v + 0.5 ); return *this; } inline fastdouble& operator += ( float v ) { value += static_cast<long long>( v * RATIO + 0.5 ); return *this; } inline fastdouble& operator -= ( float v ) { value -= static_cast<long long>( v * RATIO + 0.5 ); return *this; } inline fastdouble& operator *= ( float v ) { value = static_cast<long long>( value * v + 0.5 ); return *this; } inline fastdouble& operator /= ( float v ) { value = static_cast<long long>( value / v + 0.5 ); return *this; } inline fastdouble& operator += ( char v ) { value += static_cast<long long>( v ) << BITS; return *this; } inline fastdouble& operator -= ( char v ) { value -= static_cast<long long>( v ) << BITS; return *this; } inline fastdouble& operator *= ( char v ) { value *= v; return *this; } inline fastdouble& operator /= ( char v ) { value /= v; return *this; } inline fastdouble& operator += ( short v ) { value += static_cast<long long>( v ) << BITS; return *this; } inline fastdouble& operator -= ( short v ) { value -= static_cast<long long>( v ) << BITS; return *this; } inline fastdouble& operator *= ( short v ) { value *= v; return *this; } inline fastdouble& operator /= ( short v ) { value /= v; return *this; } inline fastdouble& operator += ( int v ) { value += static_cast<long long>( v ) << BITS; return *this; } inline fastdouble& operator -= ( int v ) { value -= static_cast<long long>( v ) << BITS; return *this; } inline fastdouble& operator *= ( int v ) { value *= v; return *this; } inline fastdouble& operator /= ( int v ) { value /= v; return *this; } inline fastdouble& operator += ( long v ) { value += static_cast<long long>( v ) << BITS; return *this; } inline fastdouble& operator -= ( long v ) { value -= static_cast<long long>( v ) << BITS; return *this; } inline fastdouble& operator *= ( long v ) { value *= v; return *this; } inline fastdouble& operator /= ( long v ) { value /= v; return *this; } inline fastdouble& operator += ( unsigned char v ) { value += static_cast<long long>( v ) << BITS; return *this; } inline fastdouble& operator -= ( unsigned char v ) { value -= static_cast<long long>( v ) << BITS; return *this; } inline fastdouble& operator *= ( unsigned char v ) { value *= v; return *this; } inline fastdouble& operator /= ( unsigned char v ) { value /= v; return *this; } inline fastdouble& operator += ( unsigned short v ) { value += static_cast<long long>( v ) << BITS; return *this; } inline fastdouble& operator -= ( unsigned short v ) { value -= static_cast<long long>( v ) << BITS; return *this; } inline fastdouble& operator *= ( unsigned short v ) { value *= v; return *this; } inline fastdouble& operator /= ( unsigned short v ) { value /= v; return *this; } inline fastdouble& operator += ( unsigned int v ) { value += static_cast<long long>( v ) << BITS; return *this; } inline fastdouble& operator -= ( unsigned int v ) { value -= static_cast<long long>( v ) << BITS; return *this; } inline fastdouble& operator *= ( unsigned int v ) { value *= v; return *this; } inline fastdouble& operator /= ( unsigned int v ) { value /= v; return *this; } inline fastdouble& operator += ( unsigned long v ) { value += static_cast<long long>( v ) << BITS; return *this; } inline fastdouble& operator -= ( unsigned long v ) { value -= static_cast<long long>( v ) << BITS; return *this; } inline fastdouble& operator *= ( unsigned long v ) { value *= v; return *this; } inline fastdouble& operator /= ( unsigned long v ) { value /= v; return *this; } //Для типа fastdouble inline bool operator < ( fastdouble r ) const { return value < r.value; } inline bool operator <= ( fastdouble r ) const { return value <= r.value; } inline bool operator > ( fastdouble r ) const { return value > r.value; } inline bool operator >= ( fastdouble r ) const { return value >= r.value; } inline bool operator == ( fastdouble r ) const { return value == r.value; } inline bool operator != ( fastdouble r ) const { return value != r.value; } }; //Для типа fastdouble inline fastdouble operator+ ( fastdouble l, fastdouble r ) { return fastdouble( l ) += r; } inline fastdouble operator- ( fastdouble l, fastdouble r ) { return fastdouble( l ) -= r; } inline fastdouble operator* ( fastdouble l, fastdouble r ) { return fastdouble( l ) *= r; } inline fastdouble operator/ ( fastdouble l, fastdouble r ) { return fastdouble( l ) /= r; } //Для типа double inline fastdouble operator + ( double l, fastdouble r ) { return fastdouble( l ) += r; } inline fastdouble operator - ( double l, fastdouble r ) { return fastdouble( l ) -= r; } inline fastdouble operator * ( double l, fastdouble r ) { return fastdouble( l ) *= r; } inline fastdouble operator / ( double l, fastdouble r ) { return fastdouble( l ) /= r; } inline fastdouble operator + ( fastdouble l, double r ) { return fastdouble( l ) += r; } inline fastdouble operator - ( fastdouble l, double r ) { return fastdouble( l ) -= r; } inline fastdouble operator * ( fastdouble l, double r ) { return fastdouble( l ) *= r; } inline fastdouble operator / ( fastdouble l, double r ) { return fastdouble( l ) /= r; } //Для типа float inline fastdouble operator + ( float l, fastdouble r ) { return fastdouble( l ) += r; } inline fastdouble operator - ( float l, fastdouble r ) { return fastdouble( l ) -= r; } inline fastdouble operator * ( float l, fastdouble r ) { return fastdouble( l ) *= r; } inline fastdouble operator / ( float l, fastdouble r ) { return fastdouble( l ) /= r; } inline fastdouble operator + ( fastdouble l, float r ) { return fastdouble( l ) += r; } inline fastdouble operator - ( fastdouble l, float r ) { return fastdouble( l ) -= r; } inline fastdouble operator * ( fastdouble l, float r ) { return fastdouble( l ) *= r; } inline fastdouble operator / ( fastdouble l, float r ) { return fastdouble( l ) /= r; } //Для типа char inline fastdouble operator + ( char l, fastdouble r ) { return fastdouble( l ) += r; } inline fastdouble operator - ( char l, fastdouble r ) { return fastdouble( l ) -= r; } inline fastdouble operator * ( char l, fastdouble r ) { return fastdouble( l ) *= r; } inline fastdouble operator / ( char l, fastdouble r ) { return fastdouble( l ) /= r; } inline fastdouble operator + ( fastdouble l, char r ) { return fastdouble( l ) += r; } inline fastdouble operator - ( fastdouble l, char r ) { return fastdouble( l ) -= r; } inline fastdouble operator * ( fastdouble l, char r ) { return fastdouble( l ) *= r; } inline fastdouble operator / ( fastdouble l, char r ) { return fastdouble( l ) /= r; } //Для типа short inline fastdouble operator + ( short l, fastdouble r ) { return fastdouble( l ) += r; } inline fastdouble operator - ( short l, fastdouble r ) { return fastdouble( l ) -= r; } inline fastdouble operator * ( short l, fastdouble r ) { return fastdouble( l ) *= r; } inline fastdouble operator / ( short l, fastdouble r ) { return fastdouble( l ) /= r; } inline fastdouble operator + ( fastdouble l, short r ) { return fastdouble( l ) += r; } inline fastdouble operator - ( fastdouble l, short r ) { return fastdouble( l ) -= r; } inline fastdouble operator * ( fastdouble l, short r ) { return fastdouble( l ) *= r; } inline fastdouble operator / ( fastdouble l, short r ) { return fastdouble( l ) /= r; } //Для типа int inline fastdouble operator + ( int l, fastdouble r ) { return fastdouble( l ) += r; } inline fastdouble operator - ( int l, fastdouble r ) { return fastdouble( l ) -= r; } inline fastdouble operator * ( int l, fastdouble r ) { return fastdouble( l ) *= r; } inline fastdouble operator / ( int l, fastdouble r ) { return fastdouble( l ) /= r; } inline fastdouble operator + ( fastdouble l, int r ) { return fastdouble( l ) += r; } inline fastdouble operator - ( fastdouble l, int r ) { return fastdouble( l ) -= r; } inline fastdouble operator * ( fastdouble l, int r ) { return fastdouble( l ) *= r; } inline fastdouble operator / ( fastdouble l, int r ) { return fastdouble( l ) /= r; } //Для типа long inline fastdouble operator + ( long l, fastdouble r ) { return fastdouble( l ) += r; } inline fastdouble operator - ( long l, fastdouble r ) { return fastdouble( l ) -= r; } inline fastdouble operator * ( long l, fastdouble r ) { return fastdouble( l ) *= r; } inline fastdouble operator / ( long l, fastdouble r ) { return fastdouble( l ) /= r; } inline fastdouble operator + ( fastdouble l, long r ) { return fastdouble( l ) += r; } inline fastdouble operator - ( fastdouble l, long r ) { return fastdouble( l ) -= r; } inline fastdouble operator * ( fastdouble l, long r ) { return fastdouble( l ) *= r; } inline fastdouble operator / ( fastdouble l, long r ) { return fastdouble( l ) /= r; } //Для типа unsigned char inline fastdouble operator + ( unsigned char l, fastdouble r ) { return fastdouble( l ) += r; } inline fastdouble operator - ( unsigned char l, fastdouble r ) { return fastdouble( l ) -= r; } inline fastdouble operator * ( unsigned char l, fastdouble r ) { return fastdouble( l ) *= r; } inline fastdouble operator / ( unsigned char l, fastdouble r ) { return fastdouble( l ) /= r; } inline fastdouble operator + ( fastdouble l, unsigned char r ) { return fastdouble( l ) += r; } inline fastdouble operator - ( fastdouble l, unsigned char r ) { return fastdouble( l ) -= r; } inline fastdouble operator * ( fastdouble l, unsigned char r ) { return fastdouble( l ) *= r; } inline fastdouble operator / ( fastdouble l, unsigned char r ) { return fastdouble( l ) /= r; } //Для типа unsigned short inline fastdouble operator + ( unsigned short l, fastdouble r ) { return fastdouble( l ) += r; } inline fastdouble operator - ( unsigned short l, fastdouble r ) { return fastdouble( l ) -= r; } inline fastdouble operator * ( unsigned short l, fastdouble r ) { return fastdouble( l ) *= r; } inline fastdouble operator / ( unsigned short l, fastdouble r ) { return fastdouble( l ) /= r; } inline fastdouble operator + ( fastdouble l, unsigned short r ) { return fastdouble( l ) += r; } inline fastdouble operator - ( fastdouble l, unsigned short r ) { return fastdouble( l ) -= r; } inline fastdouble operator * ( fastdouble l, unsigned short r ) { return fastdouble( l ) *= r; } inline fastdouble operator / ( fastdouble l, unsigned short r ) { return fastdouble( l ) /= r; } //Для типа unsigned int inline fastdouble operator + ( unsigned int l, fastdouble r ) { return fastdouble( l ) += r; } inline fastdouble operator - ( unsigned int l, fastdouble r ) { return fastdouble( l ) -= r; } inline fastdouble operator * ( unsigned int l, fastdouble r ) { return fastdouble( l ) *= r; } inline fastdouble operator / ( unsigned int l, fastdouble r ) { return fastdouble( l ) /= r; } inline fastdouble operator + ( fastdouble l, unsigned int r ) { return fastdouble( l ) += r; } inline fastdouble operator - ( fastdouble l, unsigned int r ) { return fastdouble( l ) -= r; } inline fastdouble operator * ( fastdouble l, unsigned int r ) { return fastdouble( l ) *= r; } inline fastdouble operator / ( fastdouble l, unsigned int r ) { return fastdouble( l ) /= r; } //Для типа unsigned long inline fastdouble operator + ( unsigned long l, fastdouble r ) { return fastdouble( l ) += r; } inline fastdouble operator - ( unsigned long l, fastdouble r ) { return fastdouble( l ) -= r; } inline fastdouble operator * ( unsigned long l, fastdouble r ) { return fastdouble( l ) *= r; } inline fastdouble operator / ( unsigned long l, fastdouble r ) { return fastdouble( l ) /= r; } inline fastdouble operator + ( fastdouble l, unsigned long r ) { return fastdouble( l ) += r; } inline fastdouble operator - ( fastdouble l, unsigned long r ) { return fastdouble( l ) -= r; } inline fastdouble operator * ( fastdouble l, unsigned long r ) { return fastdouble( l ) *= r; } inline fastdouble operator / ( fastdouble l, unsigned long r ) { return fastdouble( l ) /= r; } //Для типа double inline bool operator < ( fastdouble l, double r ) { return l < fastdouble( r ); } inline bool operator <= ( fastdouble l, double r ) { return l <= fastdouble( r ); } inline bool operator > ( fastdouble l, double r ) { return l > fastdouble( r ); } inline bool operator >= ( fastdouble l, double r ) { return l >= fastdouble( r ); } inline bool operator == ( fastdouble l, double r ) { return l == fastdouble( r ); } inline bool operator != ( fastdouble l, double r ) { return l != fastdouble( r ); } inline bool operator < ( double l, fastdouble r ) { return fastdouble( l ) < r; } inline bool operator <= ( double l, fastdouble r ) { return fastdouble( l ) <= r; } inline bool operator > ( double l, fastdouble r ) { return fastdouble( l ) > r; } inline bool operator >= ( double l, fastdouble r ) { return fastdouble( l ) >= r; } inline bool operator == ( double l, fastdouble r ) { return fastdouble( l ) == r; } inline bool operator != ( double l, fastdouble r ) { return fastdouble( l ) != r; } //Для типа float inline bool operator < ( fastdouble l, float r ) { return l < fastdouble( r ); } inline bool operator <= ( fastdouble l, float r ) { return l <= fastdouble( r ); } inline bool operator > ( fastdouble l, float r ) { return l > fastdouble( r ); } inline bool operator >= ( fastdouble l, float r ) { return l >= fastdouble( r ); } inline bool operator == ( fastdouble l, float r ) { return l == fastdouble( r ); } inline bool operator != ( fastdouble l, float r ) { return l != fastdouble( r ); } inline bool operator < ( float l, fastdouble r ) { return fastdouble( l ) < r; } inline bool operator <= ( float l, fastdouble r ) { return fastdouble( l ) <= r; } inline bool operator > ( float l, fastdouble r ) { return fastdouble( l ) > r; } inline bool operator >= ( float l, fastdouble r ) { return fastdouble( l ) >= r; } inline bool operator == ( float l, fastdouble r ) { return fastdouble( l ) == r; } inline bool operator != ( float l, fastdouble r ) { return fastdouble( l ) != r; } //Для типа char inline bool operator < ( fastdouble l, char r ) { return l < fastdouble( r ); } inline bool operator <= ( fastdouble l, char r ) { return l <= fastdouble( r ); } inline bool operator > ( fastdouble l, char r ) { return l > fastdouble( r ); } inline bool operator >= ( fastdouble l, char r ) { return l >= fastdouble( r ); } inline bool operator == ( fastdouble l, char r ) { return l == fastdouble( r ); } inline bool operator != ( fastdouble l, char r ) { return l != fastdouble( r ); } inline bool operator < ( char l, fastdouble r ) { return fastdouble( l ) < r; } inline bool operator <= ( char l, fastdouble r ) { return fastdouble( l ) <= r; } inline bool operator > ( char l, fastdouble r ) { return fastdouble( l ) > r; } inline bool operator >= ( char l, fastdouble r ) { return fastdouble( l ) >= r; } inline bool operator == ( char l, fastdouble r ) { return fastdouble( l ) == r; } inline bool operator != ( char l, fastdouble r ) { return fastdouble( l ) != r; } //Для типа short inline bool operator < ( fastdouble l, short r ) { return l < fastdouble( r ); } inline bool operator <= ( fastdouble l, short r ) { return l <= fastdouble( r ); } inline bool operator > ( fastdouble l, short r ) { return l > fastdouble( r ); } inline bool operator >= ( fastdouble l, short r ) { return l >= fastdouble( r ); } inline bool operator == ( fastdouble l, short r ) { return l == fastdouble( r ); } inline bool operator != ( fastdouble l, short r ) { return l != fastdouble( r ); } inline bool operator < ( short l, fastdouble r ) { return fastdouble( l ) < r; } inline bool operator <= ( short l, fastdouble r ) { return fastdouble( l ) <= r; } inline bool operator > ( short l, fastdouble r ) { return fastdouble( l ) > r; } inline bool operator >= ( short l, fastdouble r ) { return fastdouble( l ) >= r; } inline bool operator == ( short l, fastdouble r ) { return fastdouble( l ) == r; } inline bool operator != ( short l, fastdouble r ) { return fastdouble( l ) != r; } //Для типа int inline bool operator < ( fastdouble l, int r ) { return l < fastdouble( r ); } inline bool operator <= ( fastdouble l, int r ) { return l <= fastdouble( r ); } inline bool operator > ( fastdouble l, int r ) { return l > fastdouble( r ); } inline bool operator >= ( fastdouble l, int r ) { return l >= fastdouble( r ); } inline bool operator == ( fastdouble l, int r ) { return l == fastdouble( r ); } inline bool operator != ( fastdouble l, int r ) { return l != fastdouble( r ); } inline bool operator < ( int l, fastdouble r ) { return fastdouble( l ) < r; } inline bool operator <= ( int l, fastdouble r ) { return fastdouble( l ) <= r; } inline bool operator > ( int l, fastdouble r ) { return fastdouble( l ) > r; } inline bool operator >= ( int l, fastdouble r ) { return fastdouble( l ) >= r; } inline bool operator == ( int l, fastdouble r ) { return fastdouble( l ) == r; } inline bool operator != ( int l, fastdouble r ) { return fastdouble( l ) != r; } //Для типа long inline bool operator < ( fastdouble l, long r ) { return l < fastdouble( r ); } inline bool operator <= ( fastdouble l, long r ) { return l <= fastdouble( r ); } inline bool operator > ( fastdouble l, long r ) { return l > fastdouble( r ); } inline bool operator >= ( fastdouble l, long r ) { return l >= fastdouble( r ); } inline bool operator == ( fastdouble l, long r ) { return l == fastdouble( r ); } inline bool operator != ( fastdouble l, long r ) { return l != fastdouble( r ); } inline bool operator < ( long l, fastdouble r ) { return fastdouble( l ) < r; } inline bool operator <= ( long l, fastdouble r ) { return fastdouble( l ) <= r; } inline bool operator > ( long l, fastdouble r ) { return fastdouble( l ) > r; } inline bool operator >= ( long l, fastdouble r ) { return fastdouble( l ) >= r; } inline bool operator == ( long l, fastdouble r ) { return fastdouble( l ) == r; } inline bool operator != ( long l, fastdouble r ) { return fastdouble( l ) != r; } //Для типа unsigned char inline bool operator < ( fastdouble l, unsigned char r ) { return l < fastdouble( r ); } inline bool operator <= ( fastdouble l, unsigned char r ) { return l <= fastdouble( r ); } inline bool operator > ( fastdouble l, unsigned char r ) { return l > fastdouble( r ); } inline bool operator >= ( fastdouble l, unsigned char r ) { return l >= fastdouble( r ); } inline bool operator == ( fastdouble l, unsigned char r ) { return l == fastdouble( r ); } inline bool operator != ( fastdouble l, unsigned char r ) { return l != fastdouble( r ); } inline bool operator < ( unsigned char l, fastdouble r ) { return fastdouble( l ) < r; } inline bool operator <= ( unsigned char l, fastdouble r ) { return fastdouble( l ) <= r; } inline bool operator > ( unsigned char l, fastdouble r ) { return fastdouble( l ) > r; } inline bool operator >= ( unsigned char l, fastdouble r ) { return fastdouble( l ) >= r; } inline bool operator == ( unsigned char l, fastdouble r ) { return fastdouble( l ) == r; } inline bool operator != ( unsigned char l, fastdouble r ) { return fastdouble( l ) != r; } //Для типа unsigned short inline bool operator < ( fastdouble l, unsigned short r ) { return l < fastdouble( r ); } inline bool operator <= ( fastdouble l, unsigned short r ) { return l <= fastdouble( r ); } inline bool operator > ( fastdouble l, unsigned short r ) { return l > fastdouble( r ); } inline bool operator >= ( fastdouble l, unsigned short r ) { return l >= fastdouble( r ); } inline bool operator == ( fastdouble l, unsigned short r ) { return l == fastdouble( r ); } inline bool operator != ( fastdouble l, unsigned short r ) { return l != fastdouble( r ); } inline bool operator < ( unsigned short l, fastdouble r ) { return fastdouble( l ) < r; } inline bool operator <= ( unsigned short l, fastdouble r ) { return fastdouble( l ) <= r; } inline bool operator > ( unsigned short l, fastdouble r ) { return fastdouble( l ) > r; } inline bool operator >= ( unsigned short l, fastdouble r ) { return fastdouble( l ) >= r; } inline bool operator == ( unsigned short l, fastdouble r ) { return fastdouble( l ) == r; } inline bool operator != ( unsigned short l, fastdouble r ) { return fastdouble( l ) != r; } //Для типа unsigned int inline bool operator < ( fastdouble l, unsigned int r ) { return l < fastdouble( r ); } inline bool operator <= ( fastdouble l, unsigned int r ) { return l <= fastdouble( r ); } inline bool operator > ( fastdouble l, unsigned int r ) { return l > fastdouble( r ); } inline bool operator >= ( fastdouble l, unsigned int r ) { return l >= fastdouble( r ); } inline bool operator == ( fastdouble l, unsigned int r ) { return l == fastdouble( r ); } inline bool operator != ( fastdouble l, unsigned int r ) { return l != fastdouble( r ); } inline bool operator < ( unsigned int l, fastdouble r ) { return fastdouble( l ) < r; } inline bool operator <= ( unsigned int l, fastdouble r ) { return fastdouble( l ) <= r; } inline bool operator > ( unsigned int l, fastdouble r ) { return fastdouble( l ) > r; } inline bool operator >= ( unsigned int l, fastdouble r ) { return fastdouble( l ) >= r; } inline bool operator == ( unsigned int l, fastdouble r ) { return fastdouble( l ) == r; } inline bool operator != ( unsigned int l, fastdouble r ) { return fastdouble( l ) != r; } //Для типа unsigned long inline bool operator < ( fastdouble l, unsigned long r ) { return l < fastdouble( r ); } inline bool operator <= ( fastdouble l, unsigned long r ) { return l <= fastdouble( r ); } inline bool operator > ( fastdouble l, unsigned long r ) { return l > fastdouble( r ); } inline bool operator >= ( fastdouble l, unsigned long r ) { return l >= fastdouble( r ); } inline bool operator == ( fastdouble l, unsigned long r ) { return l == fastdouble( r ); } inline bool operator != ( fastdouble l, unsigned long r ) { return l != fastdouble( r ); } inline bool operator < ( unsigned long l, fastdouble r ) { return fastdouble( l ) < r; } inline bool operator <= ( unsigned long l, fastdouble r ) { return fastdouble( l ) <= r; } inline bool operator > ( unsigned long l, fastdouble r ) { return fastdouble( l ) > r; } inline bool operator >= ( unsigned long l, fastdouble r ) { return fastdouble( l ) >= r; } inline bool operator == ( unsigned long l, fastdouble r ) { return fastdouble( l ) == r; } inline bool operator != ( unsigned long l, fastdouble r ) { return fastdouble( l ) != r; } #if 1 // change to 0 to turn fastdouble usage off #else #define fastdouble double #define fasttodouble( v ) double( v ) #define fasttolong( v ) long( v ) #endif #endif //__FAST_FLOAT_H
  8. А разве можно функции, собранные в файл-библиотеку fastrts62x64x.lib, объявить как inline. Вроде бы, т. к. они уже скомпилированны в библиотеку, то они не могут быть inline.
  9. Кто пробовал для DSP фирмы Texas Instruments серии 62x или 64x пользоваться библиотекой Fast Run Time Support Library fastrts64x.lib, которая вроде бы предоставляет быструю реализацию основных операций с типами double и float. Насколько она действительно быстрее тех же операций, но встроенных в компилятор? Будет ли выигрыш? Если нет, то зачем она нужна вообще?
  10. Следующий вариант выполняется на 1 мсек быстрее, чем предыдущий. Возможно это ещё не предел оптимизации, но больше у меня идей нет. Если кто знает, то подскажите. /*!\brief Разбиение изображения на непересекающиеся области * \brief в соответствии с таблицей мод * \param Image - исходное изображение * \param Height - высота изображения * \param Width - ширина изображение * \param ModeNumb4Pix - таблица соответствия значений пикселов модам гистограммы * \param Areas - буфер результата, отражающий номера областей каждого из пикселов * \result Количество непересекающихся областей в изображении */ #include <stdlib.h> #include <csl_dat.h> //Максимальное кол-во областей в изображении #define MAX_AREAS 2000 //Ограниченный массив структур описателей областей!!! #pragma DATA_ALIGN(8); static short AreasMode[MAX_AREAS+1]; #pragma DATA_ALIGN(8); static short AreasNumber[MAX_AREAS+1]; #pragma DATA_ALIGN(8); static short AreasPixel[MAX_AREAS+1]; //Буферы для кэширования строк изображения #pragma DATA_ALIGN(8); static unsigned char ImageBuf[2][IMG_WIDTH_MAX]; #pragma DATA_ALIGN(8); static unsigned short AreasBuf[2][IMG_WIDTH_MAX]; int dsp_SplitImage2AreasFast( unsigned char ** restrict Image, int Height, int Width, unsigned char * restrict ModeNumb4Pix, unsigned short ** restrict Areas) { //Изображение последовательно просматривается по строкам //для отнесения каждого пиксела к определённой области //Вычисление площади, занимаемой каждой областью и модой register int iAreasCounter; //Счётчик количества областей в изображении register int iAreasInfoCounter;//Счётчик количества областей в контейнере //Временные переменные register int i, y, x, iSrcIndex, iDstIndex, iTmp; register int iCurrAreaNumb, iCurrModeNumb; register Uint32 id_LoadTransfer, id_SaveTransfer; register unsigned char * restrict pImageNextBuf; register unsigned char * restrict pImageCurrBuf; register unsigned short * restrict pAreasCurrBuf; register unsigned short * restrict pAreasPrevBuf; //Проверка корректности входных параметров if ((Image==0)||(ModeNumb4Pix==0)||(Areas==0)|| (Width<=0)||(Height<=0)||(Width>IMG_WIDTH_MAX)) return -1; //Установка указателя на следующую строку изображения pImageNextBuf=ImageBuf[0]; //Загрузка первой строки изображения id_LoadTransfer=DAT_copy(Image[0], pImageNextBuf, Width); //Начальная инициализация идентификатора канала сохранения id_SaveTransfer=DAT_XFRID_WAITNONE; //Обнуление счётчиков кол-ва областей iAreasCounter=iAreasInfoCounter=0; //Установка кол-ва областей максимально возможное для исключения //применения к первой строке ветви выявления связей с предыдущими строками iTmp=IMG_WIDTH_MAX; //Обнуление указателя на текущую строку pAreasCurrBuf=NULL; //Цикл по всем точкам изображения for (y=0; y<Height; y++) { //Сохранение указателя на текущую строку изображения pImageCurrBuf=pImageNextBuf; //Сохранение указателя на предыдущую строку результата pAreasPrevBuf=pAreasCurrBuf; //Указатель на следующую строку изображения pImageNextBuf=ImageBuf[(y+1)&1]; //Указатель на текущую строку результата pAreasCurrBuf=AreasBuf[y&1]; //Начальные значения номера моды iCurrModeNumb=-1; //Ожидание окончания загрузки текущей строки изображения DAT_wait(id_LoadTransfer); //Запуск загрузки следующей строки изображения id_LoadTransfer = DAT_copy(Image[y+1], pImageNextBuf, Width); //Обработка очередной строки изображения for (x=0; x<Width; x++) { //Номер моды текущей точки i=ModeNumb4Pix[pImageCurrBuf[x]]; //В зависимости от того принадлежит ли точка той же моде, //что и её левая точка, установка номера области if (iCurrModeNumb!=i) { //Добавление новой области // if (iAreasInfoCount>=MAX_AREAS) return -1; iCurrModeNumb=i; iCurrAreaNumb=iAreasInfoCounter; AreasMode[iAreasInfoCounter]=iCurrModeNumb; AreasNumber[iAreasInfoCounter]=iAreasInfoCounter; AreasPixel[iAreasInfoCounter]=x; //Инкремент счётчиков областей iAreasCounter++; iAreasInfoCounter++; } //Установка номера области текущей точки pAreasCurrBuf[x]=iCurrAreaNumb; } //Обработка всех областей в текущей строке для выявления их связей for (; iTmp<iAreasInfoCounter; iTmp++) { iSrcIndex=iTmp; iCurrModeNumb=AreasMode[iTmp]; i=AreasPixel[iTmp]; if (i>0) i--; if (iTmp==(iAreasInfoCounter-1)) iCurrAreaNumb=Width-1; else iCurrAreaNumb=AreasPixel[iTmp+1]; iCurrAreaNumb=pAreasPrevBuf[iCurrAreaNumb]; //Цикл по всем граничащим на предыдущей строке областям for (i=pAreasPrevBuf[i]; i<=iCurrAreaNumb; i++) { if (AreasMode[i]!=iCurrModeNumb) continue; //На предыдущей строке найдена область с совпадающей модой, //которая соседствует с исходной iDstIndex=i; while(AreasNumber[iDstIndex]!=iDstIndex) iDstIndex=AreasNumber[iDstIndex]; if (iSrcIndex!=iDstIndex) { //Объединение двух кластеров областей if (iSrcIndex<iDstIndex) { //Сохранение номера AreasNumber[iDstIndex]=iSrcIndex; } else { //Сохранение номера AreasNumber[iSrcIndex]=iDstIndex; //Для дальнейшего объединения берётся меньший индекс iSrcIndex=iDstIndex; } //Декремент кол-ва областей iAreasCounter--; } } } //Сохранение кол-ва областей iTmp=iAreasInfoCounter; //Ожидание окончания сохранения результата DAT_wait(id_SaveTransfer); //Сохранение строки результата id_SaveTransfer=DAT_copy(pAreasCurrBuf, Areas[y], sizeof(short)*Width); } //Обновление ссылок на области for (iSrcIndex=0; iSrcIndex<iAreasInfoCounter; iSrcIndex++) { //Поиск индекса назначения iDstIndex=iSrcIndex; while(AreasNumber[iDstIndex]!=iDstIndex) iDstIndex=AreasNumber[iDstIndex]; //Обновление номера области AreasNumber[iSrcIndex]=iDstIndex; } //Могут оставаться независимые области с индексами больше iAreasCount for (iDstIndex=-1, iSrcIndex=iAreasCounter; iSrcIndex<iAreasInfoCounter; iSrcIndex++) { //Если эта область уже переадресована - все нормально if (AreasNumber[iSrcIndex]!=iSrcIndex) continue; //Поиск индекса для переадресации for (iDstIndex++; iDstIndex<iAreasCounter; iDstIndex++) if (AreasNumber[iDstIndex]!=iDstIndex) break; //Сохранение указателя на моду AreasMode[iDstIndex]=AreasMode[iSrcIndex]; //Установка ссылки данной области на переадресованную AreasNumber[iSrcIndex]=iDstIndex; //Замена всех ссылок на эту область!!!!!!!! for (i=iSrcIndex; i<iAreasInfoCounter; i++) if (AreasNumber[i]==iSrcIndex) AreasNumber[i]=iDstIndex; } //Установка указателя на текущую загружаемую строку pAreasCurrBuf=AreasBuf[0]; //Загрузка первой строки номеров областей id_LoadTransfer=DAT_copy(Areas[0], pAreasCurrBuf, sizeof(short)*Width); //Начальная инициализация идентификатора канала сохранения id_SaveTransfer=DAT_XFRID_WAITNONE; //Обработка всех строк for (y=0; y<Height; y++) { //Сохранение указателя на предыдущую строку результата pAreasPrevBuf=pAreasCurrBuf; //Указатель на следующую строку результата pAreasCurrBuf=AreasBuf[(y+1)&1]; //Ожидание окончания загрузки текущей строки изображения DAT_wait(id_LoadTransfer); //Запуск загрузки следующей строки изображения id_LoadTransfer=DAT_copy(Areas[y+1], pAreasCurrBuf, sizeof(short)*Width); //Переписывание индексов удалённых областей на переназначенные for (x=0; x<Width; x++) pAreasPrevBuf[x]=AreasNumber[pAreasPrevBuf[x]]; //Ожидание окончания сохранения результата DAT_wait(id_SaveTransfer); //Сохранение строки результата id_SaveTransfer=DAT_copy(pAreasPrevBuf, Areas[y], sizeof(short)*Width); } //Ожидание окончания сохранения результата DAT_wait(id_SaveTransfer); return iAreasCounter; }
  11. А драйверы XDS560R установлены для CCStudio именно версии 3.2? Отсюда брали драйвер http://support.spectrumdigital.com/ccs3x_xds560r
  12. Значительно упростил вложенный цикл за счёт чуть большего расхода памяти. В результате для изображения с разрешением 640*480 процедура стала выполняться за 55 мсек. Но всё равно как-то много. Чтобы ещё такого оптимизировать? #include <stdlib.h> #include <limits.h> #include <csl_dat.h> //Максимальное кол-во областей в изображении #define MAX_AREAS 2000 //Ограниченный массив структур описателей областей!!! #pragma DATA_ALIGN(8); static short AreasMode[MAX_AREAS+1]; #pragma DATA_ALIGN(8); static short AreasNumber[MAX_AREAS+1]; #pragma DATA_ALIGN(8); static short AreasPixel[MAX_AREAS+1]; //Буферы для кэширования строк изображения #pragma DATA_ALIGN(8); static unsigned char ImageBuf[2][IMG_WIDTH_MAX]; #pragma DATA_ALIGN(8); static unsigned short AreasBuf[2][IMG_WIDTH_MAX]; int dsp_SplitImage2AreasFast( unsigned char ** restrict Image, int Height, int Width, unsigned char * restrict ModeNumb4Pix, unsigned short ** restrict Areas) { //Изображение последовательно просматривается по строкам //для отнесения каждого пиксела к определённой области //Вычисление площади, занимаемой каждой областью и модой register int iAreasCounter; //Счётчик количества областей в изображении register int iAreasInfoCounter;//Счётчик количества областей в контейнере register int iPrevAreaNumbL; //Номер области предыдущей левой точки register int iPrevModeNumbL; //Номер моды предыдущей левой точки //Временные переменные register int i, y, x, iSrcIndex, iDstIndex, iTmp; register int iCurrAreaNumb, iCurrModeNumb, iAreasInfoCountSav; register Uint32 id_LoadTransfer, id_SaveTransfer; register unsigned char * restrict pImageNextBuf; register unsigned char * restrict pImageCurrBuf; register unsigned short * restrict pAreasCurrBuf; register unsigned short * restrict pAreasPrevBuf; //Проверка корректности входных параметров if ((Image==0)||(ModeNumb4Pix==0)||(Areas==0)||(Width<=0)||(Height<=0)|| (Width>IMG_WIDTH_MAX)||(Height>IMG_HEIGHT_MAX)) return -1; //Установка указателя на следующую строку изображения pImageNextBuf=ImageBuf[0]; //Загрузка первой строки изображения id_LoadTransfer=DAT_copy(Image[0], pImageNextBuf, Width); //Начальная инициализация идентификатора канала сохранения id_SaveTransfer=DAT_XFRID_WAITNONE; //Обнуление счётчиков кол-ва областей iAreasCounter=iAreasInfoCounter=0; //Установка кол-ва областей максимально возможное для первой строки iAreasInfoCountSav=INT_MAX; //Обнуление указателя на текущую строку pAreasCurrBuf=NULL; //Цикл по всем точкам изображения for (y=0; y<Height; y++) { //Сохранение указателя на текущую строку изображения pImageCurrBuf=pImageNextBuf; //Сохранение указателя на предыдущую строку результата pAreasPrevBuf=pAreasCurrBuf; //Указатель на следующую строку изображения pImageNextBuf=ImageBuf[(y+1)&1]; //Указатель на текущую строку результата pAreasCurrBuf=AreasBuf[y&1]; //Начальные значения номера области и моды для левой точки iPrevModeNumbL=iPrevAreaNumbL=-1; //Ожидание окончания загрузки текущей строки изображения DAT_wait(id_LoadTransfer); //Запуск загрузки следующей строки изображения id_LoadTransfer = DAT_copy(Image[y+1], pImageNextBuf, Width); //Обработка очередной строки изображения for (x=0; x<Width; x++) { //Номер моды текущей точки iCurrModeNumb=ModeNumb4Pix[pImageCurrBuf[x]]; //В зависимости от того принадлежит ли точка той же моде, //что и её левая точка, установка номера области if (iCurrModeNumb==iPrevModeNumbL) iCurrAreaNumb=iPrevAreaNumbL; else { //Добавление новой области // if (iAreasInfoCount>=MAX_AREAS) return -1; iCurrAreaNumb=iAreasInfoCounter; AreasMode[iAreasInfoCounter]=iCurrModeNumb; AreasNumber[iAreasInfoCounter]=iAreasInfoCounter; AreasPixel[iAreasInfoCounter]=x; //Инкремент счётчиков областей iAreasCounter++; iAreasInfoCounter++; //Запоминание номера области и моды для левой точки iPrevAreaNumbL=iCurrAreaNumb; iPrevModeNumbL=iCurrModeNumb; } //Установка номера области текущей точки pAreasCurrBuf[x]=iCurrAreaNumb; } //Обработка всех областей в текущей строке для выявления их связей //с областями на предыдущей строке for (; iAreasInfoCountSav<iAreasInfoCounter; iAreasInfoCountSav++) { iSrcIndex=iAreasInfoCountSav; iCurrModeNumb=AreasMode[iAreasInfoCountSav]; iTmp=AreasPixel[iAreasInfoCountSav]; if (iTmp>0) iTmp--; if (iAreasInfoCountSav==(iAreasInfoCounter-1)) iCurrAreaNumb=Width-1; else iCurrAreaNumb=AreasPixel[iAreasInfoCountSav+1]; iCurrAreaNumb=pAreasPrevBuf[iCurrAreaNumb]; //Цикл по всем граничащим на предыдущей строке областям for (i=pAreasPrevBuf[iTmp]; i<=iCurrAreaNumb; i++) { if (AreasMode[i]!=iCurrModeNumb) continue; //На предыдущей строке найдена область с совпадающей модой, //которая соседствует с исходной iDstIndex=i; while(AreasNumber[iDstIndex]!=iDstIndex) iDstIndex=AreasNumber[iDstIndex]; if (iSrcIndex!=iDstIndex) { //Объединение двух кластеров областей if (iSrcIndex<iDstIndex) { //Сохранение номера AreasNumber[iDstIndex]=iSrcIndex; } else { //Сохранение номера AreasNumber[iSrcIndex]=iDstIndex; //Для дальнейшего объединения берётся меньший индекс iSrcIndex=iDstIndex; } //Декремент кол-ва областей iAreasCounter--; } } } //Сохранение кол-ва областей iAreasInfoCountSav=iAreasInfoCounter; //Ожидание окончания сохранения результата DAT_wait(id_SaveTransfer); //Сохранение строки результата id_SaveTransfer=DAT_copy(pAreasCurrBuf, Areas[y], sizeof(short)*Width); } //Обновление ссылок на области for (iSrcIndex=0; iSrcIndex<iAreasInfoCounter; iSrcIndex++) { //Поиск индекса назначения iDstIndex=iSrcIndex; while(AreasNumber[iDstIndex]!=iDstIndex) iDstIndex=AreasNumber[iDstIndex]; //Обновление номера области AreasNumber[iSrcIndex]=iDstIndex; } //Могут оставаться независимые области с индексами больше iAreasCount for (iDstIndex=-1, iSrcIndex=iAreasCounter; iSrcIndex<iAreasInfoCounter; iSrcIndex++) { //Если эта область уже переадресована - все нормально if (AreasNumber[iSrcIndex]!=iSrcIndex) continue; //Поиск индекса для переадресации for (iDstIndex++; iDstIndex<iAreasCounter; iDstIndex++) if (AreasNumber[iDstIndex]!=iDstIndex) break; //Сохранение указателя на моду AreasMode[iDstIndex]=AreasMode[iSrcIndex]; //Установка ссылки данной области на переадресованную AreasNumber[iSrcIndex]=iDstIndex; //Замена всех ссылок на эту область!!!!!!!! for (i=iSrcIndex; i<iAreasInfoCounter; i++) if (AreasNumber[i]==iSrcIndex) AreasNumber[i]=iDstIndex; } //Установка указателя на текущую загружаемую строку pAreasCurrBuf=AreasBuf[0]; //Загрузка первой строки номеров областей id_LoadTransfer=DAT_copy(Areas[0], pAreasCurrBuf, sizeof(short)*Width); //Начальная инициализация идентификатора канала сохранения id_SaveTransfer=DAT_XFRID_WAITNONE; //Обработка всех строк for (y=0; y<Height; y++) { //Сохранение указателя на предыдущую строку результата pAreasPrevBuf=pAreasCurrBuf; //Указатель на следующую строку результата pAreasCurrBuf=AreasBuf[(y+1)&1]; //Ожидание окончания загрузки текущей строки изображения DAT_wait(id_LoadTransfer); //Запуск загрузки следующей строки изображения id_LoadTransfer=DAT_copy(Areas[y+1], pAreasCurrBuf, sizeof(short)*Width); //Переписывание индексов удалённых областей на переназначенные for (x=0; x<Width; x++) pAreasPrevBuf[x]=AreasNumber[pAreasPrevBuf[x]]; //Ожидание окончания сохранения результата DAT_wait(id_SaveTransfer); //Сохранение строки результата id_SaveTransfer=DAT_copy(pAreasPrevBuf, Areas[y], sizeof(short)*Width); } //Ожидание окончания сохранения результата DAT_wait(id_SaveTransfer); return iAreasCounter; }
  13. У меня при прямом запуске CCStudio тоже виснет. Но если запускать через "CCStudio v3.3 Setup", то запускается нормально.
  14. Вот такой у меня получился код для DSP. Но для изображения размером 640*480 пикселей он выполняется за 85 мсек, что много. Что здесь можно ещё оптимизировать? #include <stdlib.h> #include <string.h> #include <csl_dat.h> //Максимальное кол-во областей в изображении #define MAX_AREAS 1000 //Максимальная ширина изображения #define IMG_WIDTH_MAX 640 //Максимальная высота изображения #define IMG_HEIGHT_MAX 480 //Макросы минимума и максимума #define max(a, b) (((a) > (b)) ? (a) : (b)) #define min(a, b) (((a) < (b)) ? (a) : (b)) //Счётчики количества областей в изображении и в контейнере static int iAreasCount=0, iAreasInfoCount=0; //Ограниченные массивы структур описателей областей!!! static short AreasMode[MAX_AREAS+1]; static short AreasNumber[MAX_AREAS+1]; //Функция создания новой области static inline int AddNewAreaInfo(const int iModeNumb) { // if (iAreasInfoCount>=MAX_AREAS) return -1; iAreasCount++; AreasMode[iAreasInfoCount]=iModeNumb; AreasNumber[iAreasInfoCount]=-1; return iAreasInfoCount++; } // Буферы для кэширования строк изображения static unsigned char ImageBuf[3][IMG_WIDTH_MAX]; static int AreasBuf[2][IMG_WIDTH_MAX]; int test_SplitImage2Areas( register unsigned char ** restrict Image, register int Height, register int Width, register short * restrict ModeNumb4Pix, register int ** restrict Areas) { //Изображение последовательно просматривается по строкам //для отнесения каждого пиксела к определённой области //Вычисление площади, занимаемой каждой областью и модой register int iPrevAreaNumbL=-1; //Номер области предыдущей левой точки register int iPrevModeNumbL=-1; //Номер моды предыдущей левой точки register int iPrevAreaNumbU=-1; //Номер области предыдущей верхней точки register int iPrevModeNumbU=-1; //Номер моды предыдущей верхней точки register int iPrevAreaNumbUL=-1; //Номер области предыдущей верхней левой точки register int iPrevModeNumbUL=-1; //Номер моды предыдущей верхней левой точки register int iPrevAreaNumbUR=-1; //Номер области предыдущей верхней правой точки register int iPrevModeNumbUR=-1; //Номер моды предыдущей верхней правой точки //Временные переменные register int i, y, x, iSrcIndex, iDstIndex, iDelta, iTmp; register int iCurrPixel, iCurrAreaNumb, iCurrModeNumb; register Uint32 id_LoadTransfer, id_SaveTransfer; register int iImageBufIndex, iAreasBufIndex; register unsigned char * restrict pImageCurrBuf; register unsigned char * restrict pImagePrevBuf; register int * restrict pAreasCurrBuf; register int * restrict pAreasPrevBuf; //Проверка корректности входных параметров if ((Image==0)||(ModeNumb4Pix==0)||(Areas==0)) return -1; if ((Width<=0)||(Height<=0)||(Width>IMG_WIDTH_MAX)||(Height>IMG_HEIGHT_MAX)) return -1; //Загрузка первой строки изображения id_LoadTransfer=DAT_copy(Image[0], ImageBuf[0], Width); //Обнуление счётчиков кол-ва областей iAreasCount=iAreasInfoCount=0; //Обработка верхней левой точки изображения iCurrPixel=Image[0][0]; iCurrModeNumb=ModeNumb4Pix[iCurrPixel]; if (iCurrModeNumb<0) { //Сканирование зигзагом окрестных точек для //выявления ближайшей с установленной модой iDelta=min(Width,Height); for (i=1; i<iDelta; i++) { iSrcIndex=-1; for (y=i, x=0; y>=0; y--, x++) { iDstIndex=Image[y][x]; iTmp=ModeNumb4Pix[iDstIndex]; if (iTmp<0) continue; iDstIndex=abs(iDstIndex-iCurrPixel); if ((iSrcIndex<0)||(iSrcIndex>iDstIndex)) { iSrcIndex=iDstIndex; iCurrModeNumb=iTmp; } } //Нашли подходящую точку - выход из поиска if (iCurrModeNumb>=0) break; } //Если точек нет, то нулевая мода if (iCurrModeNumb<0) iCurrModeNumb=0; } iCurrAreaNumb=AddNewAreaInfo(iCurrModeNumb); AreasBuf[0][0]=iCurrAreaNumb; //Указатель на текущую обрабатываемую строку изображения pImageCurrBuf=ImageBuf[0]; //Указатель на текущую результирующую строку номеров областей pAreasCurrBuf=AreasBuf[0]; //Ожидание окончания загрузки первой строки изображения while(DAT_busy(id_LoadTransfer)); //Запуск загрузки второй строки изображения id_LoadTransfer=DAT_copy(Image[1], ImageBuf[1], Width); //Обработка первой верхней строки изображения, //начиная со второго пиксела строки for (x=1; x<Width; x++) { //Запоминание номера области и моды для левой точки iPrevAreaNumbL=iCurrAreaNumb; iPrevModeNumbL=iCurrModeNumb; //Номер моды текущей точки iCurrModeNumb=ModeNumb4Pix[pImageCurrBuf[x]]; //В зависимости от наличия моды if (iCurrModeNumb<0) { iCurrModeNumb=iPrevModeNumbL; iCurrAreaNumb=iPrevAreaNumbL; } else if (iCurrModeNumb==iPrevModeNumbL) { iCurrAreaNumb=iPrevAreaNumbL; } else { //Добавление новой области iCurrAreaNumb=AddNewAreaInfo(iCurrModeNumb); } //Установка номера области текущей точки pAreasCurrBuf[x]=iCurrAreaNumb; } //Сохранение первой строки результата id_SaveTransfer=DAT_copy(AreasBuf[0], Areas[0], Width); //установка кольцевого указателя на буфер текущей строки iImageBufIndex=iAreasBufIndex=1; //Декремент ширины изображения для увеличения скорости обработки Width--; //Цикл по всем точкам изображения for (y=1; y<Height; y++) { //Сохранение указателя на предыдущую строку изображения pImagePrevBuf=pImageCurrBuf; //Сохранение указателя на предыдущую строку результата pAreasPrevBuf=pAreasCurrBuf; //Указатель на текущую строку изображения pImageCurrBuf=ImageBuf[iImageBufIndex]; //Указатель на текущую строку результата pAreasCurrBuf=AreasBuf[iAreasBufIndex]; //Продвижение индекса на следующую строку iImageBufIndex++; iImageBufIndex%=3; iAreasBufIndex++; iAreasBufIndex%=2; //Ожидание окончания загрузки текущей строки изображения while(DAT_busy(id_LoadTransfer)); //Запуск загрузки следующей строки изображения id_LoadTransfer = DAT_copy(Image[y+1], ImageBuf[iImageBufIndex], Width); //Установка начального значения для верхней левой точки iPrevAreaNumbUL=pAreasPrevBuf[0]; iPrevModeNumbUL=AreasMode[iPrevAreaNumbUL]; //Установка начального значения для верхней точки iPrevAreaNumbU=pAreasPrevBuf[1]; iPrevModeNumbU=AreasMode[iPrevAreaNumbU]; //Значение яркости первого пикселя строки iCurrPixel=pImageCurrBuf[0]; //Значение моды первого пикселя строки iPrevModeNumbL=ModeNumb4Pix[iCurrPixel]; //В зависимости от признака переходности пиксела if (iPrevModeNumbL<0) { if (abs(iCurrPixel-pImagePrevBuf[0])<abs(iCurrPixel-pImagePrevBuf[1])) { iPrevModeNumbL=iPrevModeNumbUL; iPrevAreaNumbL=iPrevAreaNumbUL; } else { iPrevModeNumbL=iPrevModeNumbU; iPrevAreaNumbL=iPrevAreaNumbU; } } else if (iPrevModeNumbL==iPrevModeNumbUL) iPrevAreaNumbL=iPrevAreaNumbUL; //Верхняя левая точка else if (iPrevModeNumbL==iPrevModeNumbU) iPrevAreaNumbL=iPrevAreaNumbU; //Верхняя точка else { //Добавление новой области iPrevAreaNumbL=AddNewAreaInfo(iPrevModeNumbL); } //Установка номера области первого пиксела строки pAreasCurrBuf[0] = iPrevAreaNumbL; //Обработка очередной строки изображения for (x=1; x<Width; x++) { //Определение параметров верхней правой точки iPrevAreaNumbUR=pAreasPrevBuf[x+1]; iPrevModeNumbUR=AreasMode[iPrevAreaNumbUR]; //Значение яркости текущего пикселя iCurrPixel=pImageCurrBuf[x]; //Номер моды текущей точки iCurrModeNumb=ModeNumb4Pix[iCurrPixel]; //В зависимости от того является ли точка переходной if (iCurrModeNumb<0) { //Текущая точка является переходной к любой области //Перебор всех точек окрестности и выбор наиболее близкой области //Левая точка iDelta=abs(pImageCurrBuf[x-1]-iCurrPixel); iCurrAreaNumb=iPrevAreaNumbL; iCurrModeNumb=iPrevModeNumbL; //Верхняя точка iTmp=abs(pImagePrevBuf[x]-iCurrPixel); if (iDelta>iTmp) { iDelta=iTmp; iCurrAreaNumb=iPrevAreaNumbU; iCurrModeNumb=iPrevModeNumbU; } //Верхняя левая точка iTmp=abs(pImagePrevBuf[x-1]-iCurrPixel); if (iDelta>iTmp) { iDelta=iTmp; iCurrAreaNumb=iPrevAreaNumbUL; iCurrModeNumb=iPrevModeNumbUL; } //Верхняя правая точка iTmp=abs(pImagePrevBuf[x+1]-iCurrPixel); if (iDelta>iTmp) { iDelta=iTmp; iCurrAreaNumb=iPrevAreaNumbUR; iCurrModeNumb=iPrevModeNumbUR; } } //Эта точка не является переходной ни к одной из мод //Просмотр всех соседних уже размеченных ранее точек //для возможного определения номера области текущей точки else if (iCurrModeNumb==iPrevModeNumbL) iCurrAreaNumb=iPrevAreaNumbL; //Левая точка else if (iCurrModeNumb==iPrevModeNumbUL) iCurrAreaNumb=iPrevAreaNumbUL; //Верхняя левая точка else if (iCurrModeNumb==iPrevModeNumbU) iCurrAreaNumb=iPrevAreaNumbU; //Верхняя точка else if (iCurrModeNumb==iPrevModeNumbUR) iCurrAreaNumb=iPrevAreaNumbUR; //Верхняя правая точка else { //Добавление новой области iCurrAreaNumb=AddNewAreaInfo(iCurrModeNumb); } //Установка номера области текущей точки pAreasCurrBuf[x] = iCurrAreaNumb; //Сканирование верхней правой точки для добавления её в список соседних областей if ((iCurrModeNumb==iPrevModeNumbUR)&&(iCurrAreaNumb!=iPrevAreaNumbUR)) { //Всего четыре возможных варианта if (AreasNumber[iCurrAreaNumb]<0) { if (AreasNumber[iPrevAreaNumbUR]>=0) { //Только добавляется ссылка на ссылочную область AreasNumber[iCurrAreaNumb]=AreasNumber[iPrevAreaNumbUR]; //Декремент кол-ва областей iAreasCount--; } else { //Обе области являются доменными iTmp=min(iCurrAreaNumb,iPrevAreaNumbUR); AreasNumber[iCurrAreaNumb]=iTmp; AreasNumber[iPrevAreaNumbUR]=iTmp; //Декремент кол-ва областей iAreasCount--; } } else //if (AreasNumber[iCurrAreaNumb]>=0) { if (AreasNumber[iPrevAreaNumbUR]<0) { //Только добавляется ссылка на ссылочную область AreasNumber[iPrevAreaNumbUR]=AreasNumber[iCurrAreaNumb]; //Декремент кол-ва областей iAreasCount--; } else { iSrcIndex=AreasNumber[iCurrAreaNumb]; iDstIndex=AreasNumber[iPrevAreaNumbUR]; if (iSrcIndex!=iDstIndex) { //Это самый трудоёмкий случай. //Но, к счастью, самый редкий! //Необходимо объединить две области if (iSrcIndex<iDstIndex) { //Обмен значениями iTmp=iSrcIndex; iSrcIndex=iDstIndex; iDstIndex=iTmp; } for (i=0; i<iAreasInfoCount; i++) { if (AreasNumber[i]==iSrcIndex) AreasNumber[i]=iDstIndex; } //Декремент кол-ва областей iAreasCount--; } } } } //Запоминание номера области и моды для левой точки iPrevAreaNumbL=iCurrAreaNumb; iPrevModeNumbL=iCurrModeNumb; //Запоминание номера области и моды для верхней левой точки iPrevAreaNumbUL=iPrevAreaNumbU; iPrevModeNumbUL=iPrevModeNumbU; //Запоминание номера области и моды для верхней точки iPrevAreaNumbU=iPrevAreaNumbUR; iPrevModeNumbU=iPrevModeNumbUR; } //Значение яркости последнего пикселя строки iCurrPixel=pImageCurrBuf[Width]; //Значение моды последнего пикселя строки iCurrModeNumb=ModeNumb4Pix[iCurrPixel]; //В зависимости от наличия моды if (iCurrModeNumb<0) { //Левая точка iDelta=abs(pImageCurrBuf[x-1]-iCurrPixel); iCurrAreaNumb=iPrevAreaNumbL; iCurrModeNumb=iPrevModeNumbL; //Верхняя левая точка iTmp=abs(pImagePrevBuf[x-1]-iCurrPixel); if (iDelta>iTmp) { iDelta=iTmp; iCurrAreaNumb=iPrevAreaNumbUL; iCurrModeNumb=iPrevModeNumbUL; } //Верхняя точка iTmp=abs(pImagePrevBuf[x]-iCurrPixel); if (iDelta>iTmp) { iDelta=iTmp; iCurrAreaNumb=iPrevAreaNumbU; iCurrModeNumb=iPrevModeNumbU; } } else if (iCurrModeNumb==iPrevModeNumbL) iCurrAreaNumb=iPrevAreaNumbL; //Левая точка else if (iCurrModeNumb==iPrevModeNumbUL) iCurrAreaNumb=iPrevAreaNumbUL; //Верхняя левая точка else if (iCurrModeNumb==iPrevModeNumbU) iCurrAreaNumb=iPrevAreaNumbU; //Верхняя правая точка else { //Добавление новой области iCurrAreaNumb=AddNewAreaInfo(iCurrModeNumb); } //Установка номера области последнего пикселя строки pAreasCurrBuf[Width]=iCurrAreaNumb; //Ожидание окончания сохранения результата while(DAT_busy(id_SaveTransfer)); //Сохранение строки результата id_SaveTransfer=DAT_copy(pAreasCurrBuf, Areas[y], Width); } //Восстановление исходной ширины изображения Width++; //Упорядочивание переадресации областей (именно здесь)!!!!! for (i=0; i<iAreasInfoCount; i++) { //Номер кластера для текущей области iTmp=AreasNumber[i]; //Пропуск кластерных областей if (iTmp<0) //Установка номера области AreasNumber[i]=i; else //Выключение области AreasMode[i]=-1; } //Могут оставаться независимые области с индексами больше iAreasCount for (iDstIndex=0, iSrcIndex=iAreasCount; iSrcIndex<iAreasInfoCount; iSrcIndex++) { //Если эта область уже переадресована - все нормально if (AreasMode[iSrcIndex]<0) continue; //Поиск индекса для переадресации for (/*задаётся вовне*/; iDstIndex<iAreasCount; iDstIndex++) if (AreasMode[iDstIndex]<0) break; //Сохранение указателя на моду AreasMode[iDstIndex]=AreasMode[iSrcIndex]; //Выключение переадресуемой области AreasMode[iSrcIndex]=-1; //Установка ссылки данной области на переадресованную AreasNumber[iSrcIndex]=iDstIndex; //Замена всех ссылок на эту область!!!!!!!! for (i=0; i<iAreasInfoCount; i++) if (AreasNumber[i]==iSrcIndex) AreasNumber[i]=iDstIndex; } //Загрузка первой строки номеров областей id_LoadTransfer=DAT_copy(Areas[0], AreasBuf[0], Width); //Установка кольцевого указателя iAreasBufIndex=0; //Начальная инициализация идентификатора канала сохранения id_SaveTransfer=DAT_XFRID_WAITNONE; //Обработка всех строк for (y=0; y<Height; y++) { //Указатель на текущую строку результата pAreasCurrBuf=AreasBuf[iAreasBufIndex]; //Продвижение индекса на следующую строку iAreasBufIndex^=1; //Ожидание окончания загрузки текущей строки изображения while(DAT_busy(id_LoadTransfer)); //Запуск загрузки следующей строки изображения id_LoadTransfer=DAT_copy(Areas[y+1], AreasBuf[iAreasBufIndex], Width); //Переписывание индексов удалённых областей на переназначенные for (x=0; x<Width; x++) pAreasCurrBuf[x]=AreasNumber[pAreasCurrBuf[x]]; //Ожидание окончания сохранения результата while(DAT_busy(id_SaveTransfer)); //Сохранение строки результата id_SaveTransfer=DAT_copy(pAreasCurrBuf, Areas[y], Width); } //Ожидание окончания сохранения результата while(DAT_busy(id_SaveTransfer)); return iAreasCount; }
×
×
  • Создать...