|
Операции с плавающей точкой без FPU, На сколько падает производительность? |
|
|
|
 |
Ответов
|
Apr 24 2008, 13:33
|
Частый гость
 
Группа: Свой
Сообщений: 178
Регистрация: 30-12-04
Из: Москва
Пользователь №: 1 762

|
Цитата(fontp @ Apr 22 2008, 11:21)  Нужна затем, чтобы уйти от стандарта IEEE и игнорировать всякие overflow/underflow. Как всегда проверки на ошибки забирают большую часть усилий и вся мощь уходит зазря. В Borland C тоже всегда был "fast float" и смысл тот же - не делать проверок и ускориться раза в 2. Насколько быстро это всё будет для TI? Да не очень . Раз в 50-100 медленнее такта процессора (т.е. вычислений fixed). Длинна слова-то - стандартная и мантисса/порядок не выровнены на границу 16 бит Сделал для функций этой библиотеки обёртку. Но оказалось, что с ней интересующая меня функция билинейного масштабирования работает даже медленее, чем при использовании встроенных в компилятор типа double. Из-за чего это? Может из-за накладных расходов на организацию классов? Код /*!\file fast_rts64x.h * \brief Быстрая реализация основных операций с числами * \brief с плавающей запятой для DSP фирмы Texas Instruments * \brief серии 64x, основанная на библиотеке fast_rts64x.lib * \version 1.0 * \date 2008 */ #ifndef __FAST_RTS_64X_H #define __FAST_RTS_64X_H
#ifdef __cplusplus extern "C" { #include <fastrts62x64x.h> } #else #include <fastrts62x64x.h> #endif
class double_fst { public: double value;
inline double_fst( double v=0 ) { value=v; } inline double_fst( float v ) { value=spdp(v); } inline double_fst( char v ) { value=intdp(v); } inline double_fst( short v ) { value=intdp(v); } inline double_fst( int v ) { value=intdp(v); } inline double_fst( long v ) { value=longdp(v); } inline double_fst( unsigned char v ) { value=uintdp(v); } inline double_fst( unsigned short v ) { value=uintdp(v); } inline double_fst( unsigned int v ) { value=uintdp(v); } inline double_fst( unsigned long v ) { value=ulongdp(v); }
inline operator double() const { return value; } inline operator float() const { return dpsp(value); } inline operator char() const { return (char)dpint(value); } inline operator short() const { return (short)dpint(value); } inline operator int() const { return dpint(value); } inline operator long() const { return dplong(value); } inline operator unsigned char() const { return (unsigned char)dpuint(value); } inline operator unsigned short() const { return (unsigned short)dpuint(value); } inline operator unsigned int() const { return dpuint(value); } inline operator unsigned long() const { return dpulong(value); }
inline void operator = ( double_fst r ) { value=r.value; } inline void operator = ( double v ) { value=v; } inline void operator = ( float v ) { value=spdp(v); } inline void operator = ( char v ) { value=intdp(v); } inline void operator = ( short v ) { value=intdp(v); } inline void operator = ( int v ) { value=intdp(v); } inline void operator = ( long v ) { value=longdp(v); } inline void operator = ( unsigned char v ) { value=uintdp(v); } inline void operator = ( unsigned short v ) { value=uintdp(v); } inline void operator = ( unsigned int v ) { value=uintdp(v); } inline void operator = ( unsigned long v ) { value=ulongdp(v); }
inline void operator += ( double_fst r ) { value=adddp(value, r.value); } inline void operator -= ( double_fst r ) { value=subdp(value, r.value); } inline void operator *= ( double_fst r ) { value=mpydp(value, r.value); } inline void operator /= ( double_fst r ) { value=divdp(value, r.value); }
inline void operator += ( double v ) { value=adddp(value, v); } inline void operator -= ( double v ) { value=subdp(value, v); } inline void operator *= ( double v ) { value=mpydp(value, v); } inline void operator /= ( double v ) { value=divdp(value, v); }
inline void operator += ( float v ) { value=adddp(value, spdp(v)); } inline void operator -= ( float v ) { value=subdp(value, spdp(v)); } inline void operator *= ( float v ) { value=mpydp(value, spdp(v)); } inline void operator /= ( float v ) { value=divdp(value, spdp(v)); }
inline void operator += ( char v ) { value=adddp(value, intdp(v)); } inline void operator -= ( char v ) { value=subdp(value, intdp(v)); } inline void operator *= ( char v ) { value=mpydp(value, intdp(v)); } inline void operator /= ( char v ) { value=divdp(value, intdp(v)); }
inline void operator += ( short v ) { value=adddp(value, intdp(v)); } inline void operator -= ( short v ) { value=subdp(value, intdp(v)); } inline void operator *= ( short v ) { value=mpydp(value, intdp(v)); } inline void operator /= ( short v ) { value=divdp(value, intdp(v)); }
inline void operator += ( int v ) { value=adddp(value, intdp(v)); } inline void operator -= ( int v ) { value=subdp(value, intdp(v)); } inline void operator *= ( int v ) { value=mpydp(value, intdp(v)); } inline void operator /= ( int v ) { value=divdp(value, intdp(v)); }
inline void operator += ( long v ) { value=adddp(value, longdp(v)); } inline void operator -= ( long v ) { value=subdp(value, longdp(v)); } inline void operator *= ( long v ) { value=mpydp(value, longdp(v)); } inline void operator /= ( long v ) { value=divdp(value, longdp(v)); }
inline void operator += ( unsigned char v ) { value=adddp(value, uintdp(v)); } inline void operator -= ( unsigned char v ) { value=subdp(value, uintdp(v)); } inline void operator *= ( unsigned char v ) { value=mpydp(value, uintdp(v)); } inline void operator /= ( unsigned char v ) { value=divdp(value, uintdp(v)); }
inline void operator += ( unsigned short v ) { value=adddp(value, uintdp(v)); } inline void operator -= ( unsigned short v ) { value=subdp(value, uintdp(v)); } inline void operator *= ( unsigned short v ) { value=mpydp(value, uintdp(v)); } inline void operator /= ( unsigned short v ) { value=divdp(value, uintdp(v)); }
inline void operator += ( unsigned int v ) { value=adddp(value, uintdp(v)); } inline void operator -= ( unsigned int v ) { value=subdp(value, uintdp(v)); } inline void operator *= ( unsigned int v ) { value=mpydp(value, uintdp(v)); } inline void operator /= ( unsigned int v ) { value=divdp(value, uintdp(v)); }
inline void operator += ( unsigned long v ) { value=adddp(value, ulongdp(v)); } inline void operator -= ( unsigned long v ) { value=subdp(value, ulongdp(v)); } inline void operator *= ( unsigned long v ) { value=mpydp(value, ulongdp(v)); } inline void operator /= ( unsigned long v ) { value=divdp(value, ulongdp(v)); }
inline bool operator < ( double_fst &r ) const { return value < r.value; } inline bool operator > ( double_fst &r ) const { return value > r.value; } inline bool operator <= ( double_fst &r ) const { return value <= r.value; } inline bool operator >= ( double_fst &r ) const { return value >= r.value; } inline bool operator == ( double_fst &r ) const { return value == r.value; } inline bool operator != ( double_fst &r ) const { return value != r.value; }
inline bool operator < ( double v ) const { return value < v; } inline bool operator > ( double v ) const { return value > v; } inline bool operator <= ( double v ) const { return value <= v; } inline bool operator >= ( double v ) const { return value >= v; } inline bool operator == ( double v ) const { return value == v; } inline bool operator != ( double v ) const { return value != v; }
inline bool operator < ( float v ) const { return value < spdp(v); } inline bool operator > ( float v ) const { return value > spdp(v); } inline bool operator <= ( float v ) const { return value <= spdp(v); } inline bool operator >= ( float v ) const { return value >= spdp(v); } inline bool operator == ( float v ) const { return value == spdp(v); } inline bool operator != ( float v ) const { return value != spdp(v); }
inline bool operator < ( char v ) const { return value < intdp(v); } inline bool operator > ( char v ) const { return value > intdp(v); } inline bool operator <= ( char v ) const { return value <= intdp(v); } inline bool operator >= ( char v ) const { return value >= intdp(v); } inline bool operator == ( char v ) const { return value == intdp(v); } inline bool operator != ( char v ) const { return value != intdp(v); }
inline bool operator < ( short v ) const { return value < intdp(v); } inline bool operator > ( short v ) const { return value > intdp(v); } inline bool operator <= ( short v ) const { return value <= intdp(v); } inline bool operator >= ( short v ) const { return value >= intdp(v); } inline bool operator == ( short v ) const { return value == intdp(v); } inline bool operator != ( short v ) const { return value != intdp(v); }
inline bool operator < ( int v ) const { return value < intdp(v); } inline bool operator > ( int v ) const { return value > intdp(v); } inline bool operator <= ( int v ) const { return value <= intdp(v); } inline bool operator >= ( int v ) const { return value >= intdp(v); } inline bool operator == ( int v ) const { return value == intdp(v); } inline bool operator != ( int v ) const { return value != intdp(v); }
inline bool operator < ( long v ) const { return value < longdp(v); } inline bool operator > ( long v ) const { return value > longdp(v); } inline bool operator <= ( long v ) const { return value <= longdp(v); } inline bool operator >= ( long v ) const { return value >= longdp(v); } inline bool operator == ( long v ) const { return value == longdp(v); } inline bool operator != ( long v ) const { return value != longdp(v); }
inline bool operator < ( unsigned char v ) const { return value < uintdp(v); } inline bool operator > ( unsigned char v ) const { return value > uintdp(v); } inline bool operator <= ( unsigned char v ) const { return value <= uintdp(v); } inline bool operator >= ( unsigned char v ) const { return value >= uintdp(v); } inline bool operator == ( unsigned char v ) const { return value == uintdp(v); } inline bool operator != ( unsigned char v ) const { return value != uintdp(v); }
inline bool operator < ( unsigned short v ) const { return value < uintdp(v); } inline bool operator > ( unsigned short v ) const { return value > uintdp(v); } inline bool operator <= ( unsigned short v ) const { return value <= uintdp(v); } inline bool operator >= ( unsigned short v ) const { return value >= uintdp(v); } inline bool operator == ( unsigned short v ) const { return value == uintdp(v); } inline bool operator != ( unsigned short v ) const { return value != uintdp(v); }
inline bool operator < ( unsigned int v ) const { return value < uintdp(v); } inline bool operator > ( unsigned int v ) const { return value > uintdp(v); } inline bool operator <= ( unsigned int v ) const { return value <= uintdp(v); } inline bool operator >= ( unsigned int v ) const { return value >= uintdp(v); } inline bool operator == ( unsigned int v ) const { return value == uintdp(v); } inline bool operator != ( unsigned int v ) const { return value != uintdp(v); }
inline bool operator < ( unsigned long v ) const { return value < ulongdp(v); } inline bool operator > ( unsigned long v ) const { return value > ulongdp(v); } inline bool operator <= ( unsigned long v ) const { return value <= ulongdp(v); } inline bool operator >= ( unsigned long v ) const { return value >= ulongdp(v); } inline bool operator == ( unsigned long v ) const { return value == ulongdp(v); } inline bool operator != ( unsigned long v ) const { return value != ulongdp(v); } };
//Для типа double_fst inline double_fst operator + (double_fst l, double_fst r) { return double_fst(adddp(l.value,r.value)); } inline double_fst operator - (double_fst l, double_fst r) { return double_fst(subdp(l.value,r.value)); } inline double_fst operator * (double_fst l, double_fst r) { return double_fst(mpydp(l.value,r.value)); } inline double_fst operator / (double_fst l, double_fst r) { return double_fst(divdp(l.value,r.value)); }
//Для типа double inline double_fst operator + ( double l, double_fst r ) { return double_fst(adddp(l, r.value)); } inline double_fst operator - ( double l, double_fst r ) { return double_fst(subdp(l, r.value)); } inline double_fst operator * ( double l, double_fst r ) { return double_fst(mpydp(l, r.value)); } inline double_fst operator / ( double l, double_fst r ) { return double_fst(divdp(l, r.value)); } inline double_fst operator + ( double_fst l, double r ) { return double_fst(adddp(l.value, r)); } inline double_fst operator - ( double_fst l, double r ) { return double_fst(subdp(l.value, r)); } inline double_fst operator * ( double_fst l, double r ) { return double_fst(mpydp(l.value, r)); } inline double_fst operator / ( double_fst l, double r ) { return double_fst(divdp(l.value, r)); }
//Для типа float inline double_fst operator + ( float l, double_fst r ) { return double_fst(adddp(spdp(l), r.value)); } inline double_fst operator - ( float l, double_fst r ) { return double_fst(subdp(spdp(l), r.value)); } inline double_fst operator * ( float l, double_fst r ) { return double_fst(mpydp(spdp(l), r.value)); } inline double_fst operator / ( float l, double_fst r ) { return double_fst(divdp(spdp(l), r.value)); } inline double_fst operator + ( double_fst l, float r ) { return double_fst(adddp(l.value, spdp(r))); } inline double_fst operator - ( double_fst l, float r ) { return double_fst(subdp(l.value, spdp(r))); } inline double_fst operator * ( double_fst l, float r ) { return double_fst(mpydp(l.value, spdp(r))); } inline double_fst operator / ( double_fst l, float r ) { return double_fst(divdp(l.value, spdp(r))); }
//Для типа char inline double_fst operator + ( char l, double_fst r ) { return double_fst(adddp(intdp(l), r.value)); } inline double_fst operator - ( char l, double_fst r ) { return double_fst(subdp(intdp(l), r.value)); } inline double_fst operator * ( char l, double_fst r ) { return double_fst(mpydp(intdp(l), r.value)); } inline double_fst operator / ( char l, double_fst r ) { return double_fst(divdp(intdp(l), r.value)); } inline double_fst operator + ( double_fst l, char r ) { return double_fst(adddp(l.value, intdp(r))); } inline double_fst operator - ( double_fst l, char r ) { return double_fst(subdp(l.value, intdp(r))); } inline double_fst operator * ( double_fst l, char r ) { return double_fst(mpydp(l.value, intdp(r))); } inline double_fst operator / ( double_fst l, char r ) { return double_fst(divdp(l.value, intdp(r))); }
//Для типа short inline double_fst operator + ( short l, double_fst r ) { return double_fst(adddp(intdp(l), r.value)); } inline double_fst operator - ( short l, double_fst r ) { return double_fst(subdp(intdp(l), r.value)); } inline double_fst operator * ( short l, double_fst r ) { return double_fst(mpydp(intdp(l), r.value)); } inline double_fst operator / ( short l, double_fst r ) { return double_fst(divdp(intdp(l), r.value)); } inline double_fst operator + ( double_fst l, short r ) { return double_fst(adddp(l.value, intdp(r))); } inline double_fst operator - ( double_fst l, short r ) { return double_fst(subdp(l.value, intdp(r))); } inline double_fst operator * ( double_fst l, short r ) { return double_fst(mpydp(l.value, intdp(r))); } inline double_fst operator / ( double_fst l, short r ) { return double_fst(divdp(l.value, intdp(r))); }
//Для типа int inline double_fst operator + ( int l, double_fst r ) { return double_fst(adddp(intdp(l), r.value)); } inline double_fst operator - ( int l, double_fst r ) { return double_fst(subdp(intdp(l), r.value)); } inline double_fst operator * ( int l, double_fst r ) { return double_fst(mpydp(intdp(l), r.value)); } inline double_fst operator / ( int l, double_fst r ) { return double_fst(divdp(intdp(l), r.value)); } inline double_fst operator + ( double_fst l, int r ) { return double_fst(adddp(l.value, intdp(r))); } inline double_fst operator - ( double_fst l, int r ) { return double_fst(subdp(l.value, intdp(r))); } inline double_fst operator * ( double_fst l, int r ) { return double_fst(mpydp(l.value, intdp(r))); } inline double_fst operator / ( double_fst l, int r ) { return double_fst(divdp(l.value, intdp(r))); }
//Для типа long inline double_fst operator + ( long l, double_fst r ) { return double_fst(adddp(longdp(l), r.value)); } inline double_fst operator - ( long l, double_fst r ) { return double_fst(subdp(longdp(l), r.value)); } inline double_fst operator * ( long l, double_fst r ) { return double_fst(mpydp(longdp(l), r.value)); } inline double_fst operator / ( long l, double_fst r ) { return double_fst(divdp(longdp(l), r.value)); } inline double_fst operator + ( double_fst l, long r ) { return double_fst(adddp(l.value, longdp(r))); } inline double_fst operator - ( double_fst l, long r ) { return double_fst(subdp(l.value, longdp(r))); } inline double_fst operator * ( double_fst l, long r ) { return double_fst(mpydp(l.value, longdp(r))); } inline double_fst operator / ( double_fst l, long r ) { return double_fst(divdp(l.value, longdp(r))); }
//Для типа unsigned char inline double_fst operator + ( unsigned char l, double_fst r ) { return double_fst(adddp(uintdp(l), r.value)); } inline double_fst operator - ( unsigned char l, double_fst r ) { return double_fst(subdp(uintdp(l), r.value)); } inline double_fst operator * ( unsigned char l, double_fst r ) { return double_fst(mpydp(uintdp(l), r.value)); } inline double_fst operator / ( unsigned char l, double_fst r ) { return double_fst(divdp(uintdp(l), r.value)); } inline double_fst operator + ( double_fst l, unsigned char r ) { return double_fst(adddp(l.value, uintdp(r))); } inline double_fst operator - ( double_fst l, unsigned char r ) { return double_fst(subdp(l.value, uintdp(r))); } inline double_fst operator * ( double_fst l, unsigned char r ) { return double_fst(mpydp(l.value, uintdp(r))); } inline double_fst operator / ( double_fst l, unsigned char r ) { return double_fst(divdp(l.value, uintdp(r))); }
//Для типа unsigned short inline double_fst operator + ( unsigned short l, double_fst r ) { return double_fst(adddp(uintdp(l), r.value)); } inline double_fst operator - ( unsigned short l, double_fst r ) { return double_fst(subdp(uintdp(l), r.value)); } inline double_fst operator * ( unsigned short l, double_fst r ) { return double_fst(mpydp(uintdp(l), r.value)); } inline double_fst operator / ( unsigned short l, double_fst r ) { return double_fst(divdp(uintdp(l), r.value)); } inline double_fst operator + ( double_fst l, unsigned short r ) { return double_fst(adddp(l.value, uintdp(r))); } inline double_fst operator - ( double_fst l, unsigned short r ) { return double_fst(subdp(l.value, uintdp(r))); } inline double_fst operator * ( double_fst l, unsigned short r ) { return double_fst(mpydp(l.value, uintdp(r))); } inline double_fst operator / ( double_fst l, unsigned short r ) { return double_fst(divdp(l.value, uintdp(r))); }
//Для типа unsigned int inline double_fst operator + ( unsigned int l, double_fst r ) { return double_fst(adddp(uintdp(l), r.value)); } inline double_fst operator - ( unsigned int l, double_fst r ) { return double_fst(subdp(uintdp(l), r.value)); } inline double_fst operator * ( unsigned int l, double_fst r ) { return double_fst(mpydp(uintdp(l), r.value)); } inline double_fst operator / ( unsigned int l, double_fst r ) { return double_fst(divdp(uintdp(l), r.value)); } inline double_fst operator + ( double_fst l, unsigned int r ) { return double_fst(adddp(l.value, uintdp(r))); } inline double_fst operator - ( double_fst l, unsigned int r ) { return double_fst(subdp(l.value, uintdp(r))); } inline double_fst operator * ( double_fst l, unsigned int r ) { return double_fst(mpydp(l.value, uintdp(r))); } inline double_fst operator / ( double_fst l, unsigned int r ) { return double_fst(divdp(l.value, uintdp(r))); }
//Для типа unsigned long inline double_fst operator + ( unsigned long l, double_fst r ) { return double_fst(adddp(ulongdp(l), r.value)); } inline double_fst operator - ( unsigned long l, double_fst r ) { return double_fst(subdp(ulongdp(l), r.value)); } inline double_fst operator * ( unsigned long l, double_fst r ) { return double_fst(mpydp(ulongdp(l), r.value)); } inline double_fst operator / ( unsigned long l, double_fst r ) { return double_fst(divdp(ulongdp(l), r.value)); } inline double_fst operator + ( double_fst l, unsigned long r ) { return double_fst(adddp(l.value, ulongdp(r))); } inline double_fst operator - ( double_fst l, unsigned long r ) { return double_fst(subdp(l.value, ulongdp(r))); } inline double_fst operator * ( double_fst l, unsigned long r ) { return double_fst(mpydp(l.value, ulongdp(r))); } inline double_fst operator / ( double_fst l, unsigned long r ) { return double_fst(divdp(l.value, ulongdp(r))); }
#endif //__FAST_RTS_64X_H
|
|
|
|
|
Apr 25 2008, 06:08
|
Частый гость
 
Группа: Новичок
Сообщений: 84
Регистрация: 4-09-07
Из: Москва
Пользователь №: 30 277

|
Цитата(fontp @ Apr 24 2008, 17:39)  Обёртка, то ладно...Надеюсь, все функции библиотеки объявлены как inline. Иначе - беда. Издержки на вызов функции А разве можно функции, собранные в файл-библиотеку fastrts62x64x.lib, объявить как inline. Вроде бы, т. к. они уже скомпилированны в библиотеку, то они не могут быть inline.
|
|
|
|
|
Apr 25 2008, 07:16
|

Эксперт
    
Группа: Свой
Сообщений: 1 467
Регистрация: 25-06-04
Пользователь №: 183

|
Цитата(Degun @ Apr 25 2008, 10:08)  А разве можно функции, собранные в файл-библиотеку fastrts62x64x.lib, объявить как inline. Вроде бы, т. к. они уже скомпилированны в библиотеку, то они не могут быть inline. Так чего Вы тогда от него хотите? Короткие функции, вызываемые через Call по определению будут работать медленно. Для стандартных float это не так, они оформлены intrinsic и вставляются компилятором inline А вот Вы возьмите не библиотеку lib, а её исходный код. Повытаскивайте те функции, что Вам нужны в h-файл и припишите к каждой функции модификатор inline - и всё сразу станет во много раз быстрее.
|
|
|
|
Сообщений в этой теме
sigmaN Операции с плавающей точкой без FPU Apr 3 2008, 10:21 fontp Можно, только не в 3-5, а скорее раз 8-10
Для этог... Apr 3 2008, 10:29 sigmaN Цитата(fontp @ Apr 3 2008, 13:29) Можно, ... Apr 3 2008, 12:57  fontp Цитата(sigmaN @ Apr 3 2008, 16:57) Да уж.... Apr 3 2008, 13:33   DRUID3 Цитата(fontp @ Apr 3 2008, 16:33) Если ни... Apr 3 2008, 14:24    fontp Цитата(DRUID3 @ Apr 3 2008, 18:24) Я ещ... Apr 3 2008, 14:31     sigmaN Цитата(fontp @ Apr 3 2008, 17:31) Он хоче... Apr 3 2008, 14:54     DRUID3 Цитата(fontp @ Apr 3 2008, 17:31) Он хоче... Apr 3 2008, 14:58 Stanislav Цитата(sigmaN @ Apr 3 2008, 14:21) Интере... Apr 3 2008, 14:59 sigmaN Цитата(Stanislav @ Apr 3 2008, 17:59) Нел... Apr 3 2008, 17:13  Stanislav Цитата(sigmaN @ Apr 3 2008, 21:13) В обще... Apr 3 2008, 18:38   fontp Цитата(Stanislav @ Apr 3 2008, 22:38) ЗЗЫ... Apr 4 2008, 06:21    Stanislav Цитата(fontp @ Apr 4 2008, 10:21) SPEEX C... Apr 4 2008, 07:30     fontp Цитата(Stanislav @ Apr 4 2008, 11:30) Не ... Apr 4 2008, 07:52      Stanislav Цитата(fontp @ Apr 4 2008, 11:52) С 6.3 я... Apr 4 2008, 10:50       fontp Цитата(Stanislav @ Apr 4 2008, 14:50) Есл... Apr 4 2008, 11:15 sigmaN Господа, ну послушайте не сэмплы с сайта, которые ... Apr 4 2008, 08:50 fontp Цитата(sigmaN @ Apr 4 2008, 12:50) Господ... Apr 4 2008, 09:10 sigmaN Сэмплы MELPe-PLUS
Даааа, послушал я MELPe-Plus 4... Apr 4 2008, 19:35      Degun Цитата(fontp @ Apr 25 2008, 11:16) Так че... Apr 25 2008, 12:49 Andrew32768 ... а если переписать этот класс с использованием ... Jun 17 2008, 13:37 fontp Цитата(Andrew32768 @ Jun 17 2008, 17:37) ... Jun 17 2008, 14:00  Andrew32768 Цитата(fontp @ Jun 17 2008, 20:00) Как эт... Jun 17 2008, 14:18   fontp Цитата(Andrew32768 @ Jun 17 2008, 18:18) ... Jun 17 2008, 14:45
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|