Форум программистов, компьютерный форум CyberForum.ru

Оптимизация кода - C++

Восстановить пароль Регистрация
 
Mr.Armik
2 / 2 / 0
Регистрация: 11.06.2010
Сообщений: 88
13.07.2012, 13:28     Оптимизация кода #1
В С++ я совсем недавно, вот задали задачку:
Перемножить 2 матрицы MxМ, элементами которых являются матрицы NxN.
Код я вроде написал, но при увеличении размерности M > 75 программа просто перестает работать, а заглянув в диспетчер задач я обнаружил что оперативы используется больше 1 гигабайта.
Подскажите где я не правильно что то делаю.

Вот сам код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
const int N = 4;
const int M = 100;
 
    //заполнение матрицы размерностью nxn случайными числами
double** generation(int n)
{
    double **a = new double*[n*sizeof(double)];
    for(int i=0;i<n;i++)
    {
        a[i] = new double[n*sizeof(double)];
        for(int j=0;j<n;j++)
            a[i][j] = rand()%100;
    }
    return a;
}
//перемножение матриц a и b
double** multiply (double **a,double **b)
{
    double **c = new double*[N*sizeof(double)];
    for(int i=0;i<N;i++)
    {
        c[i] = new double[N*sizeof(double)];
        for(int j=0;j<N;j++)
            c[i][j] = 0;
    }
 
    for (int i=0;i<N;i++)
        for(int j=0;j<N;j++)
            for (int k=0;k<N;k++)
                c[i][j]+=a[i][k]*b[k][j];
    return c;
}
    //суммирование матриц (NxN)
double** summ (double **a, double **b)
{
    double **c = new double*[N*sizeof(double)];
    for(int i=0;i<N;i++)
    {
        c[i] = new double[N*sizeof(double)];
        for(int j=0;j<N;j++)
            c[i][j] = 0;
    }
    for (int i=0;i<N;i++)
        for(int j=0;j<N;j++)
            c[i][j] = a[i][j]+b[i][j];
    return c;
}
 
int main(array<System::String ^> ^args)
{
    double **c;
    char tmp;
    cout<<"Enter any cymbol."<<endl;
    cin>>tmp;
    double **x[M][M],**y[M][M],**z[M][M];
    cout<<"Generation..."<<endl;
    for (int i=0;i<M;i++)
        for(int j=0;j<M;j++)
        {
            x[i][j] = generation(N);
            y[i][j] = generation(N);
            z[i][j] = generation(N);
        }
    cout<<"Colculation..."<<endl;
    clock_t t1 = clock(); //время до выполнения
    for (int i=0;i<M;i++)
        for(int j=0;j<M;j++)
        {
            for (int k=0;k<M;k++)
            {
                c = multiply(x[i][k],y[k][j]);
                z[i][j] = summ(z[i][j],c);
            }
        }
    clock_t t2 = clock(); // время после
    cout<<"Successful."<<endl;
    cout << "Time: " << (double) (t2-t1) / (double)CLOCKS_PER_SEC << '\n'; // время в секундах
    cin>>tmp;
    return 0;
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
13.07.2012, 13:28     Оптимизация кода
Посмотрите здесь:

Оптимизация кода C++
C++ Оптимизация кода
оптимизация кода! C++
Оптимизация кода C++
C++ Оптимизация кода
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
13.07.2012, 13:56     Оптимизация кода #2
Замените во всех операторах new n*sizeof( double ) на n. Иначе Вы выделяете память не под n элементов типа double а под n * sizeof( double ). Оператор new выделяет память не в байтах, а в количестве элементов. Дальше код не смотрел.
Intel~lect
 Аватар для Intel~lect
135 / 124 / 2
Регистрация: 03.07.2012
Сообщений: 355
13.07.2012, 14:06     Оптимизация кода #3
Цитата Сообщение от Toshkarik Посмотреть сообщение
Иначе Вы выделяете память не под n элементов типа double а под n * sizeof( double ).
Тогда получается что памяти выделяется в 8 раз больше чем нужно?
Mr.Armik
2 / 2 / 0
Регистрация: 11.06.2010
Сообщений: 88
13.07.2012, 14:16  [ТС]     Оптимизация кода #4
Спс большое за совет, немного помогло. Но все же при размерности основной матрицы больше 150 приложение даже не досчитывает, выскакивает Windows окошко RunTime Error...
CheshireCat
Эксперт С++
2907 / 1235 / 78
Регистрация: 27.05.2008
Сообщений: 3,309
13.07.2012, 14:22     Оптимизация кода #5
Ну еще бы. Память по new ты выделяешь, а кто будет ее освобождать??
Я уже давал совет:
Мне самым простым решением представляется разработка класса матрицы, который "умеет" перемножать матрицу на матрицу; ну, может быть, еще на константу и на вектор, если потребуется. В противном случае, ты очень-очень лехко запутаешься со всеми этими ***mass и будешь искать ошибки очень долго.
Этот момент настал - теперь ты будешь искать ошибки очень долго.

Как видишь, много времени не потребовалось.... :-)
Mr.Armik
2 / 2 / 0
Регистрация: 11.06.2010
Сообщений: 88
13.07.2012, 17:59  [ТС]     Оптимизация кода #6
На счет выделения памяти, читал я в книгах что в С++ не обязательно следить за освобождением памяти, как это было в С. И используется вручную только при необходимости работать со одними переменными много раз в одном блоке. Если бы все так было плачевно как вы говорите, то после 2-х запусков я б убил бы свой комп.
Jupiter
13.07.2012, 18:10
  #7

Не по теме:

Цитата Сообщение от Mr.Armik Посмотреть сообщение
На счет выделения памяти, читал я в книгах что в С++ не обязательно следить за освобождением памяти, как это было в С
[sarcasm]вот это новости, что ж тогда вас привело на этот форум? вы же все правильно делаете[/sarcasm]

Mr.Armik
2 / 2 / 0
Регистрация: 11.06.2010
Сообщений: 88
13.07.2012, 18:15  [ТС]     Оптимизация кода #8
Ищу совета, а не упреков, типо : я же вам говорил...

А на словах и я могу во многих сферах надавать советов. Вот только толку от них будет мало.

Я же конкретики просил. Вот человек мне конкретно указал на мою ошибку, и я осознал ее и исправил.
Jupiter
Каратель
Эксперт C++
6543 / 3963 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
13.07.2012, 18:20     Оптимизация кода #9
Цитата Сообщение от Mr.Armik Посмотреть сообщение
На счет выделения памяти, читал я в книгах что в С++ не обязательно следить за освобождением памяти, как это было в С.
вы ошибаетесь, в языках Си/С++, не было и нет сборщика мусора, да нынешние ОС очистят память по завершении процесса, но "не стоит полгаться на технику"(с)
Mr.Armik
2 / 2 / 0
Регистрация: 11.06.2010
Сообщений: 88
13.07.2012, 19:05  [ТС]     Оптимизация кода #10
При размерах матриц MxM, где M=175, получается 175х175х25 (25 объем маленьких матриц)
это получается 765625 ячеек типо double. А у меня 2 матрицы такие + 1 результирующая, вот по этому так и лагает наверное. У меня всего то 2гига аперативы.

Или я ошибаюсь?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.07.2012, 12:23     Оптимизация кода
Еще ссылки по теме:

C++ оптимизация кода
оптимизация кода C++
Оптимизация кода C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Mr.Armik
2 / 2 / 0
Регистрация: 11.06.2010
Сообщений: 88
19.07.2012, 12:23  [ТС]     Оптимизация кода #11
Вдруг кому то пригодится. Выкладываю рабочий код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#include <stdlib.h>
#include <time.h>
#include <iostream>
#include <conio.h>
#include <time.h>
 
using namespace std;
 
const int N = 4;
const int M = 200;
    //заполнение матрицы размерностью nxn случайными числами
double** generation(int n)
{
    double **a;
    a = (double**)malloc(sizeof(double *)*n);
    for(int i=0;i<n;i++)
    {
        a[i] = (double*)malloc(sizeof(double)*n);
        for(int j=0;j<n;j++)
            a[i][j] = rand()%100;
    }
    return a;
}
 
    //вывод на консоль матрицы
void print(double **c)
{
    for (int i=0;i<N;i++)
    {
        for (int j=0;j<N;j++)
            printf("%7.0f",c[i][j]);
        cout<<"\n";
    }
}
    //перемножение матриц a и b
void multiply (double **a,double **b,double **c)
{
    for (int i=0;i<N;i++)
        for(int j=0;j<N;j++)
            for (int k=0;k<N;k++)
                c[i][j]+=a[i][k]*b[k][j];
}
 
    //суммирование матриц
void summ (double **a, double **b,double **c)
{
    for (int i=0;i<N;i++)
        for(int j=0;j<N;j++)
            c[i][j] = a[i][j]+b[i][j];
}
 
int main(int argc, char**argv)
{
    cout<<"Enter any cymbol."<<endl;
    _getch();
    double **x[M][M],**y[M][M],**z[M][M];
    double **c;
    
    c = (double**)malloc(sizeof(double *)*N);
    for(int i=0;i<N;i++)
        c[i] = (double*)malloc(sizeof(double)*N);
    
    cout<<"Generation..."<<endl;
    for (int i=0;i<M;i++)
        for(int j=0;j<M;j++)
        {
            x[i][j] = generation(N);
            y[i][j] = generation(N);
            z[i][j] = generation(N);
        }
    cout<<"Colculation..."<<endl;
    clock_t t1 = clock(); //время до выполнения
    for (int i=0;i<M;i++)
        for(int j=0;j<M;j++)
            for (int k=0;k<M;k++)
            {
                multiply(x[i][k],y[k][j],c);
                summ(z[i][j],c,z[i][j]);
            }
 
    clock_t t2 = clock(); // время после
    cout<<"Successful."<<endl;
    cout << "Time: " << (double) (t2-t1) / (double)CLOCKS_PER_SEC << '\n'; // время в секундах
    return 0;
}
Код не идеальный, но все же рабочий, может кому то пригодится для начала работы...
Yandex
Объявления
19.07.2012, 12:23     Оптимизация кода
Ответ Создать тему
Опции темы

Текущее время: 07:34. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru