Имеется кусок кода который выполняется почти 1 секунду: Код (Text): const int size = 500; static double F[size][size]; static double tm[size][size]; for(m=0; m<size; m++) { /// немного кода //вот собственно отсюда и идет весь провал времени. //можно ли как нить оптимизировать работу с массивом //ибо слишком много времени тратится на присвоение вычисленного значения в массив for( q = 0; q<size; q++) { tm[0][q] +=F[m][q]*t; } }
tm[0][q] заменить локальной переменной. Использовать указатели. Сделать раскрутку цикла. Использовать операции над упакованными данными(инстрикси и другие расширения).
подключил компилятором раскрутку циклов, задействовал sse. но мне вот что не дает покоя: double temp = tm[q]+F[m][q]*2; double ttl = 0.447384; tm[q] = temp; // or ttl в переменной temp значение порядка равного ttl. но вот присвоение ttl проходит за 0.25 секунд, а temp при 0.8. Не могу понять почему такое происходит?
Что-то у вас странное происходит. Код (Text): #include <iostream> #include <windows.h> const int size = 500; static double F[size][size]; static double tm[size][size]; int main (int argc, char* argv[]) { LARGE_INTEGER frequency; bool bHpet = QueryPerformanceFrequency(&frequency); std::cout<<"HPET = "<<std::boolalpha<<bHpet<<std::endl; LARGE_INTEGER counterStart; QueryPerformanceCounter(&counterStart); const int t = 2; for(int m=0; m<size; m++) { for(int q = 0; q<size; q++) { tm[0][q] +=F[m][q]*t; } } LARGE_INTEGER counterEnd; QueryPerformanceCounter(&counterEnd); double time = (double(counterEnd.QuadPart - counterStart.QuadPart)) / (double)frequency.QuadPart; std::cout<<"time = "<<time<<"sec."<<std::endl; } time = 0.0025seс.
меж коментариев затерялось: Код (Text): for(int m=0; m<size; m++) { for(int i=0; i<size; i++) { for(int q = 0; q<size; q++) { tm[0][q] +=F[m][q]*t; } } } for(int i=0; i<size; i++) -- вот тута и проблема во времени. непомню откуда оно взялось. щас буду проверять
Pavia Booster Возможно не все так просто) или наоборот Код (Text): #include <iostream> #include <windows.h> #include <ctime> const int size = 500; static float A[size][size]; static float b[size][size]; static float F[size][size]; static float tm[size][size]; using namespace std; int main () { //генерация матриц int e = rand(); for(int p=0;p<size;p++) { b[p][0] = e; for(int j=0; j<size; j++) { int h = rand(); A[p][j]=h; if(p == j) { F[p][j] =1; }else { F[p][j] = 0; } } } //засекаем время выполения clock_t tStart; tStart = clock(); int m,i; for(m=0; m<size; m++) { for(i=0; i<size; i++) { //проверка первого условия if(i+1 != m+1) { //выполнение второго условия float t1=0,t2=0; //разбиваем действие на поддействия, находим отдельно числитель и знаменатель, //потом обрабатываем for(int k = 0; k<size; k++) { t1 += F[i][k]*A[k][m]; t2 += F[m][k]*A[k][m]; } double t = t1/t2; int fpc = _fpclass(t); switch(fpc) { case _FPCLASS_QNAN: t=0; break; case _FPCLASS_NINF: t=0; break; case _FPCLASS_PINF: t=0; break; } // cout << t << "\n"; for(int q = 0; q<size; q++) { tm[0][q] = tm[0][q]+(F[m][q])*(t); } for(int w = 0; w<size; w++) { F[i][w] = F[i][w] - tm[0][w]; } } } } cout << (float)(clock() - tStart) / CLOCKS_PER_SEC << "\n"; return 0; } так вот прикол начинается с того что если t вычисляется как t1/t2 то время порядка 1 секунды, если t поставить любое число то время снижается до 0.2 не мойму как оно может влиять. Алгоритм работает верно, это какаято модификация решения слау, писал когдато по алгоритму предложенным преподавателем в универе. щас подумаю как выкинуть цикл можно, но не думаю что получится
Думаю для начало нужно хотя-бы разобраться, что это за метод решения и затем переписать в более читабельный вид.
Код (Text): double*p=F;// Взяли указатель на начало массива(адрес 1-го элемента) int q=0; int length = size*size; for(int i=0 ; i<length ; i++, q++) { if (q>(size-1)) q=0; tm[0][q] += ((*p++)*size)*t; }; Идея в следующем: если ты объявляешь статический массив как F[size][size], тогда все значения в нём содержаться последовательно и можно обойтись одинарным циклом для обхода двухмерного массива. Цикл for(int i=0; i<size; i++) не нужен, он заменяется умножением на size, если я правильно понял алго Код писал без компилятора, на память, так что надо проверять.
artkar понятно, попробую завтра, но всетаки непонятно почему при постоянной и переменной t меняется время.
ring4 У меня ваш код выполняется очень долго. Оптимизация. Этот кусок компилятор может вообще выбросить. Код (Text): for(int k = 0; k<size; k++) { t1 += F[i][k]*A[k][m]; t2 += F[m][k]*A[k][m]; } И почему бы эти два цикла не объединить в один? Код (Text): for(int q = 0; q<size; q++) { tm[0][q] = tm[0][q]+(F[m][q])*(t); } for(int w = 0; w<size; w++) { F[i][w] = F[i][w] - tm[0][w]; }
Booster честно писал давно,да побыстрей чтобы сдать работу, а щас данный метод пригодился в реальной жизни. А не льзя объеденить т.к это реализация формулы и там сначала нужно все просумировать. щас попробую написать формулу если интересно, это модификация метода исключения гауса.
вот то что соответствует коду: http://--------- не не то, здесь какаято модификация модификации) лучше завтра на трезвую голову подумаю
ring4 По-моему можно, так как суммируется по разными рядам - if(i != m). Вообще слау действительно затратные. Если нужна скорость, то могу посоветовать gpu. Недавно фракталы на gpu считал, профит поимел нехилый.
gpu попробую, но для начала планирую всетаки написать нормальный "линейный" код а потом распаралелить его. проц. 30% производительности для 2 ядреных систем должно быть. а там видно будет. ну для gpu я думаю должна быть нормальная видюха, а тут более вероятно что многоядерный проц быстрее будет, чем топовая видео карта
это просто ЛОЛ, с БОЛЬШОЙ БУКВЫ ЛОЛ. Мой 4х ядерный квадр, просто отдыхает по сравнению с моей GTS 250, а она давно не топ. Причем отдыхает, раз так в 10-15 минимум.