Здравствуйте, MaximE, Вы писали:
>> gcc expression templates может оптимизировать? >> что-то мой (3.4.2) при -O3 в два проигрывает ручному коду.
ME>Пробовал -fomit-frame-pointer и/или современную версию gcc?
1-е пробовал. 2-е нет.
вот простенький исходник. можешь запустить?
#include <iostream>
#include <time.h>
template< typename T, int iSize, int jSize >
struct array_view
{
typedef T array_type [iSize][jSize];
typedef T & result_type;
array_type & arr;
array_view ( array_type & src ) : arr (src) { }
array_view & operator = ( array_view const & rhs );
template< class Expr >
array_view & operator = ( Expr const & rhs ) {
for ( int i=0; i<iSize; ++i ) for ( int j=0; j<jSize; ++j ) arr[i][j]=rhs(i,j);
return *this;
}
result_type operator () ( int i, int j ) const { return this->arr[i][j]; }
};
template< int iSize, int jSize, typename T >
inline array_view<T,iSize,jSize> matrix ( T (&src) [iSize][jSize] ) { return array_view<T,iSize,jSize> (src); }
template< typename R, typename T1, typename T2 >
struct add_expr {
T1 const & a;
T2 const & b;
add_expr ( T1 const & x, T2 const & y ) : a(x), b(y) {}
R operator () ( int i, int j ) const { return a(i,j)+b(i,j); }
};
template< typename R, typename T1, typename T2 >
inline add_expr<R,T1,T2> add ( T1 const & x, T2 const & y ) {
return add_expr<R,T1,T2> (x,y);
}
template< int count, int si, int sj >
void test () {
int a [si][sj];
int x [si][sj];
int y [si][sj];
int z [si][sj];
int s = 0;
for ( int u=0; u<si; ++u ) for ( int v=0; v<sj; ++v, ++s ) { a[u][v] = y[u][v] = x[u][v] = z[u][v] = s; }
{
time_t b = time(0);
for ( int c=0; c<count; ++c ) for ( int u=0; u<si; ++u ) for ( int v=0; v<sj; ++v ) a[u][v] = x[u][v]+y[u][v]+z[u][v]+a[u][v];
time_t e = time(0);
std::cout << "array: " << difftime (e,b) << std::endl;
}
{
time_t b = time(0);
for ( int c=0; c<count; ++c ) matrix(a) = add<int> ( matrix(x),add<int>(matrix(y),add<int>(matrix(z),matrix(a))));
time_t e = time(0);
std::cout << "expression: " << difftime (e,b) << std::endl;
}
}
int main ()
{
test <400000000,3,3> ();
}
NB>template< int count, int si, int sj >
NB>void test () {
NB> int a [si][sj];
NB> int x [si][sj];
NB> int y [si][sj];
NB> int z [si][sj];
NB> int s = 0;
NB> for ( int u=0; u<si; ++u ) for ( int v=0; v<sj; ++v, ++s ) { a[u][v] = y[u][v] = x[u][v] = z[u][v] = s; }
NB> {
boost::progress_timer t;
NB> // time_t b = time(0);
NB> for ( int c=0; c<count; ++c ) for ( int u=0; u<si; ++u ) for ( int v=0; v<sj; ++v ) a[u][v] = x[u][v]+y[u][v]+z[u][v]+a[u][v];
NB> // time_t e = time(0);
NB> std::cout << "array: ";
NB> }
NB> {
boost::progress_timer t;
NB> // time_t b = time(0);
NB> for ( int c=0; c<count; ++c ) matrix(a) = add<int> ( matrix(x),add<int>(matrix(y),add<int>(matrix(z),matrix(a))));
NB> // time_t e = time(0);
NB> std::cout << "expression: ";
NB> }
NB>}
NB>int main ()
NB>{
NB> test <400000000,3,3> ();
NB>}
NB>
и вот что получилось:
zaufi tests # g++ --version
i686-pc-linux-gnu-g++ (GCC) 3.4.6 (Gentoo 3.4.6-r1, ssp-3.4.5-1.0, pie-8.7.9)
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
zaufi tests # g++ -O3 -o mt mt.cc
zaufi tests # ./mt
array: 9.88 s
expression: 20.03 s
zaufi tests # g++ -fomit-frame-pointer -O3 -o mt mt.cc
zaufi tests # ./mt
array: 9.47 s
expression: 18.10 s
zaufi tests # g++-4.1.1 -fomit-frame-pointer -O3 -o mt mt.cc
zaufi tests # ./mt
array: 5.88 s
expression: 5.93 s
zaufi tests # g++-4.1.1 -ftree-vectorize -fomit-frame-pointer -O3 -o mt mt.cc
zaufi tests # ./mt
array: 5.87 s
expression: 5.93 s
zaufi tests # uname -a
Linux zaufi 2.6.17-gentoo-r4 #2 PREEMPT Wed Aug 16 20:59:43 MSD 2006 i686 Intel(R) Pentium(R) 4 CPU 3.00GHz GenuineIntel GNU/Linux
zaufi tests #
Здравствуйте, zaufi, Вы писали:
Z>я тут поменял замер времени чутка:
Z>Здравствуйте, night beast, Вы писали:
NB>>вот простенький исходник. можешь запустить?
[]
Z>и вот что получилось: Z>
Z>zaufi tests # g++-4.1.1 -fomit-frame-pointer -O3 -o mt mt.cc
Z>zaufi tests # ./mt
Z>array: 5.88 s
Z>expression: 5.93 s
Z>zaufi tests # g++-4.1.1 -ftree-vectorize -fomit-frame-pointer -O3 -o mt mt.cc
Z>zaufi tests # ./mt
Z>array: 5.87 s
Z>expression: 5.93 s
Z>
Интересно увидеть прирост от использования -fomit-frame-pointer с gcc 4.1.1.
Здравствуйте, MaximE, Вы писали:
ME>Интересно увидеть прирост от использования -fomit-frame-pointer с gcc 4.1.1.
вот позапускал несколько раз... второй знак посе запятой как видно это погрешность измерений... проводить по (как минимум) 30 экспериментов мя ессно заломало -- луче прогу поменять
zaufi tests # g++-4.1.1 -O3 -o mt mt.cc
zaufi tests # ./mt
array: 5.89 s
expression: 5.90 s
zaufi tests # g++-4.1.1 -ftree-vectorize -fomit-frame-pointer -O3 -o mt mt.cc
zaufi tests # ./mt
array: 5.91 s
expression: 5.94 s
zaufi tests # g++-4.1.1 -fomit-frame-pointer -O3 -o mt mt.cc
zaufi tests # ./mt
array: 5.89 s
expression: 5.93 s
zaufi tests # ./mt
array: 5.90 s
expression: 5.94 s
zaufi tests # g++-4.1.1 -O3 -o mt mt.cc
zaufi tests # ./mt
array: 5.90 s
expression: 5.90 s
zaufi tests # g++-4.1.1 -O3 -o mt mt.cc
zaufi tests # ./mt
array: 5.91 s
expression: 5.91 s
zaufi tests # ./mt
array: 5.88 s
expression: 5.90 s
zaufi tests # ./mt
array: 5.90 s
expression: 5.89 s
zaufi tests #
Здравствуйте, zaufi, Вы писали:
Z>Здравствуйте, MaximE, Вы писали:
ME>>Интересно увидеть прирост от использования -fomit-frame-pointer с gcc 4.1.1.
Z>вот позапускал несколько раз... второй знак посе запятой как видно это погрешность измерений... проводить по (как минимум) 30 экспериментов мя ессно заломало -- луче прогу поменять
Z>
Z>zaufi tests # g++-4.1.1 -O3 -o mt mt.cc
Z>zaufi tests # ./mt
Z>array: 5.89 s
Z>expression: 5.90 s
Z>zaufi tests # g++-4.1.1 -ftree-vectorize -fomit-frame-pointer -O3 -o mt mt.cc
Z>zaufi tests # ./mt
Z>array: 5.91 s
Z>expression: 5.94 s
Z>zaufi tests # g++-4.1.1 -fomit-frame-pointer -O3 -o mt mt.cc
Z>zaufi tests # ./mt
Z>array: 5.89 s
Z>expression: 5.93 s
Z>zaufi tests # ./mt
Z>array: 5.90 s
Z>expression: 5.94 s
Z>zaufi tests # g++-4.1.1 -O3 -o mt mt.cc
Z>zaufi tests # ./mt
Z>array: 5.90 s
Z>expression: 5.90 s
Z>zaufi tests # g++-4.1.1 -O3 -o mt mt.cc
Z>zaufi tests # ./mt
Z>array: 5.91 s
Z>expression: 5.91 s
Z>zaufi tests # ./mt
Z>array: 5.88 s
Z>expression: 5.90 s
Z>zaufi tests # ./mt
Z>array: 5.90 s
Z>expression: 5.89 s
Z>zaufi tests #
Z>
Т.е. разницы особого вкдада от -fomit-frame-pointer с gcc 4.1.1 не видно, так?
Тест можно было бы сделать более точным, добавив несколько холостых прогревочных циклов, чтобы pre-fault страницы и "разогреть" кэши процессора.
Здравствуйте, zaufi, Вы писали:
NB>>спасибо. а то я уж было совсем в гсс разочаровался NB>>есть еще флаг -funroll-all-loops но на отношение он повлиять не должен.
Z>луче почитать про то как правильно делать цыклы оптимизируемые по -ftree-vectorize
Здравствуйте, night beast, Вы писали:
NB>Здравствуйте, zaufi, Вы писали:
NB>>>спасибо. а то я уж было совсем в гсс разочаровался NB>>>есть еще флаг -funroll-all-loops но на отношение он повлиять не должен.
Z>>луче почитать про то как правильно делать цыклы оптимизируемые по -ftree-vectorize
NB>эт можно. где читать?
точного урла не вспомню... гуглом находиться должно -- был мануал от чуваков делавших автовекторизатор я читал по диагонали оставив это "на досуг"...