Форум программистов, компьютерный форум, киберфорум
Наши страницы

C++

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 14, средняя оценка - 4.64
Kastaneda
Jesus loves me
Эксперт С++
4701 / 2905 / 239
Регистрация: 12.12.2009
Сообщений: 7,399
Записей в блоге: 2
Завершенные тесты: 1
#1

Почему код, написанный на С++, в разы быстрее работает с большим объемом памяти, чем с маленьким? - C++

07.02.2012, 12:20. Просмотров 1742. Ответов 15
Метки нет (Все метки)

Привет!
Понадобилось мне сравнить скорость работы идентичных алгоритмов на Fortran и C++. Алгоритм - перемножение матриц. Решил поэкспериментировать с матрицами разных размеров.
Вот результаты
________________________C++____________Fortran
Матрицы100*100 (~80 КБ)
10000 перемножений______10,96 сек________10,97 сек
Матрицы 365*365 (~1МБ)
200 перемножений_________10,26 сек_______12,56 сек
Матрицы 1150*1150 (~10МБ)
1 перемножение____________2,4 сек________14,8 сек
По моему на 10 МБ С++ показывает просто поразительный результат. Как вы думаете, с чем это может быть связанно?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
07.02.2012, 12:20
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Почему код, написанный на С++, в разы быстрее работает с большим объемом памяти, чем с маленьким? (C++):

Написал код в Full Debug, потом переделал в Release - и написанный код не работает - C++ Builder
Кто сталкивался с проблемой, написал код в Full Debug потом переделал в Release и написанный код не работает (((

Сравнение строк или какой код быстрее работает ? - C++ Builder
пример strcmp(AnsiString(DBGrid1->Columns->Items->FieldName).c_str(), AnsiString(Main->IndexFieldNames).c_str()); есть ещё ...

Режим отладки (Debug) работает в 2 раза быстрее, чем реализованная, как готовое приложение (Release) - C++ Builder
Объективно, почему программа на С++ Bilder ( содержит цикл в 6500 повторений и в каждое повторение выодит в выходной файл out.csv 100...

Почему код не работает хотя ошибок нет? Что-то не так с выделением памяти? - C++
#include <math.h> #include <stdio.h> #include <conio.h> #include <iostream> using namespace std; int n = 0; double a, b; ...

Работа с большим объемом данных - C++
Имеется загруженное изоображение с помощью opencv. Задача: вывести цвета изображения с из колличеством. Цвет задаю структурой, хранящей...

C# работает быстрее чем С++ - C++
имеется файл типа 6 1.0 2.0 3.0 4 5 6 7 1.0 2.0 3.0 4 5 6 7 1.0 2.0 3.0 4 5 6 7 1.0 2.0 3.0 4 5 6 7 1.0 2.0 3.0 4 5 6 7 1.0...

15
NoMasters
Псевдослучайный
1765 / 1107 / 74
Регистрация: 13.09.2011
Сообщений: 3,153
07.02.2012, 12:27 #2
Цитата Сообщение от Kastaneda Посмотреть сообщение
Как вы думаете, с чем это может быть связанно?
Либо с тем, что ты не умеешь писать на фортране, либо с используемыми компиляторами.
0
Kastaneda
Jesus loves me
Эксперт С++
4701 / 2905 / 239
Регистрация: 12.12.2009
Сообщений: 7,399
Записей в блоге: 2
Завершенные тесты: 1
07.02.2012, 13:08  [ТС] #3
Цитата Сообщение от NoMasters Посмотреть сообщение
Либо с тем, что ты не умеешь писать на фортране, либо с используемыми компиляторами.
На фортране я писать не умею, но дело не в этом. Алгоритм я переложил один в один:
Fortran
1
2
3
4
5
6
7
8
9
10
    do n=0, count
        do k=1,size
            do i=1,size
                do j=1,size
                    c(k,i)=c(k,i) + a(k,j) * b(j,i) ! a и b исходные матрицы, с - результирующая
                enddo
            enddo
        enddo
        !c = 0
    enddo
C++
1
2
3
4
5
6
7
8
9
   while(count--) {
        for(size_t i = 0; i < size; i++) {
            for(size_t j = 0; j < size; j++) {
                for(size_t n = 0; n < size; n++) {
                    C[i][j] += A[i][n] * B[j][n];
                }
            }
        }
    }
Интересно другое, на С++ разительно отличаются показатели в зависимости от размера матриц и от кол-ва перемножений.

P.S. компилятор g++, хотя по моему это не важно
0
CheshireCat
Эксперт С++
2896 / 1245 / 78
Регистрация: 27.05.2008
Сообщений: 3,411
07.02.2012, 13:32 #4
1. Воспроизводится ли результат теста на другой машине (другого разработчика, etc.)?
2. Воспроизводится ли при сборке другим компилятором?

3. Перепроверь еще раз код теста. Он точно корректный? Нет UB или чего-нибудь подобного? Нет многопоточных блокировок или чего-нибудь подобного? Короче, можно ли безоговорочно доверять тесту?

Disclaimer:
Все эти вопросы - не для того, чтобы уличить тебя в каких-то ошибках или т.п., а - чтобы понять, в каком же направлении двигаться и искать разгадку.....
0
Imate
120 / 76 / 8
Регистрация: 08.06.2011
Сообщений: 267
07.02.2012, 13:35 #5
g++ по умолчанию вроде оптимизирует ;/
0
Kastaneda
Jesus loves me
Эксперт С++
4701 / 2905 / 239
Регистрация: 12.12.2009
Сообщений: 7,399
Записей в блоге: 2
Завершенные тесты: 1
07.02.2012, 14:25  [ТС] #6
Цитата Сообщение от CheshireCat Посмотреть сообщение
1. Воспроизводится ли результат теста на другой машине (другого разработчика, etc.)?
2. Воспроизводится ли при сборке другим компилятором?
Пока что нет возможности проверить

Цитата Сообщение от CheshireCat Посмотреть сообщение
3. Перепроверь еще раз код теста. Он точно корректный? Нет UB или чего-нибудь подобного? Нет многопоточных блокировок или чего-нибудь подобного? Короче, можно ли безоговорочно доверять тесту?
С кодом все в порядке. К тому же с другими размерами матриц результаты вменяемые, подозрителен только С++ тест с 10МБ.
0
NoMasters
Псевдослучайный
1765 / 1107 / 74
Регистрация: 13.09.2011
Сообщений: 3,153
07.02.2012, 16:22 #7
Цитата Сообщение от Kastaneda Посмотреть сообщение
компилятор g++
То есть gfortran против g++? Попробуй руками задать одинаковые опции оптимизации.
0
niXman
Эксперт С++
3139 / 1451 / 49
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
07.02.2012, 18:35 #8
Kastaneda, какие опции используешь при сборке?
приложи компилябельный код как для С++ так и для фортрана, плиз.
0
Kastaneda
Jesus loves me
Эксперт С++
4701 / 2905 / 239
Регистрация: 12.12.2009
Сообщений: 7,399
Записей в блоге: 2
Завершенные тесты: 1
07.02.2012, 19:19  [ТС] #9
Цитата Сообщение от niXman Посмотреть сообщение
Kastaneda, какие опции используешь при сборке?
Честно говоря не особо задавлся этим вопросом. Тест был просто чтобы убедиться, что С++ быстрее, поэтому использовал дефолтные опции.
Код завтра выложу.

Добавлено через 37 секунд
Цитата Сообщение от NoMasters Посмотреть сообщение
То есть gfortran против g++
Да, именно так.
0
ForEveR
В астрале
Эксперт С++
7985 / 4744 / 321
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
07.02.2012, 19:21 #10
Kastaneda, Ну g++ по дефолту компилит с -O2.
А вот gfortran - хз.
0
go
Эксперт С++
3586 / 1366 / 129
Регистрация: 16.04.2009
Сообщений: 4,528
07.02.2012, 22:03 #11
Kastaneda, странное время какое-то. Без вашего кода здесь никак.
да и алгоритм перемножения не понятный.
0
Kastaneda
Jesus loves me
Эксперт С++
4701 / 2905 / 239
Регистрация: 12.12.2009
Сообщений: 7,399
Записей в блоге: 2
Завершенные тесты: 1
08.02.2012, 08:20  [ТС] #12
Цитата Сообщение от CheshireCat Посмотреть сообщение
3. Перепроверь еще раз код теста. Он точно корректный? Нет UB или чего-нибудь подобного? Нет многопоточных блокировок или чего-нибудь подобного? Короче, можно ли безоговорочно доверять тесту?
Все таки напортачил с индексами) Сегодня свежим взглядом посмотрел, переписал.
Теперь результат больше похож на правду - на 10Мб - С++ ~8,12 сек, Fortran - ~31,5 сек.
Т.е. с увиличением объема матрицы и при этом уменьшением перемножений С++ уменьшает время подсчета, а Фортран увеличивает. Думаю в С++ все дело в кол-ве переходов, а вот Фортран похоже качественно другой код генерит. Пока некогда в ассемблерном коде ковыряться.

Исходники (С++ под Linux):
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
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <iomanip>
#include <algorithm>
 
int main()
{
    const size_t size = 1150;
    size_t count = 1;
    double **A, **B, **C;
 
    A = new double*[size];
    B = new double*[size];
    C = new double*[size];
 
    std::generate_n(A, size, [=](){return new double[size];});
    std::generate_n(B, size, [=](){return new double[size];});
    std::generate_n(C, size, [=](){return new double[size];});
 
    srand(time(NULL));
 
    for(size_t i = 0; i < size; i++) {
        std::generate_n(A[i], size, rand);
        std::generate_n(B[i], size, rand);
        std::fill_n(C[i], size, 0);
    }
 
    std::cout << "Start calculation..." << std::endl;
    timespec time_start, time_end;
    clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time_start);
 
    while(count--) {
        for (int k = 0; k < size; ++k) {
            for (int i = 0; i < size; ++i) {
                for (int j = 0; j < size; ++j) {
                    C[i][k] += A[i][j] * B[j][k];
                }
            }
        }
    }
 
    clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time_end);
 
    int result_sec = time_end.tv_sec - time_start.tv_sec;
    int result_nsec;
    const int nanoseconds = 1E9;
 
    if(time_end.tv_nsec > time_start.tv_nsec) {
        result_nsec = time_end.tv_nsec - time_start.tv_nsec;
    } else {
        --result_sec;
        result_nsec = nanoseconds - time_start.tv_nsec + time_end.tv_nsec;
    }
 
    std::cout << "Time calculation: " << result_sec << "," <<  result_nsec << std::endl;
 
    std::for_each(A, A + size, [](double*& ptr){delete []ptr;});
    std::for_each(B, B + size, [](double*& ptr){delete []ptr;});
    std::for_each(C, C + size, [](double*& ptr){delete []ptr;});
 
    delete []A;
    delete []B;
    delete []C;
 
    return 0;
}
Fortran
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
program mulmatrix
    integer, parameter :: size = 1150, count = 1
    integer(4) i,j,k
    real(8), allocatable :: a(:,:),b(:,:),c(:,:)
 
    allocate(a(1:size, 1:size))
    allocate(b(1:size, 1:size))
    allocate(c(1:size, 1:size))
 
    call random_seed
    call random_number(a)
    call random_number(b)
    c = 0
 
    write(*,*) 'Start calculation...'
    time = second()
 
    do n=0, count
        do k=1,size
            do i=1,size
                do j=1,size
                    c(i,k)=c(i,j) + a(k,j) * b(j,k)
                enddo
            enddo
        enddo
    enddo
 
    time = second() - time
    write(*,*) 'Time calculation: ', time
 
    deallocate(a)
    deallocate(b)
    deallocate(c)
end program mulmatrix
0
go
Эксперт С++
3586 / 1366 / 129
Регистрация: 16.04.2009
Сообщений: 4,528
08.02.2012, 20:46 #13
Цитата Сообщение от Kastaneda Посмотреть сообщение
Теперь результат больше похож на правду - на 10Мб - С++ ~8,12 сек,
Лично у меня
Bash
1
2
3
4
‘‚@ANDREY-PC /c/mingw
$ kast.exe
Start calculation...
Time calculation: 32,729009800
0
Kastaneda
Jesus loves me
Эксперт С++
4701 / 2905 / 239
Регистрация: 12.12.2009
Сообщений: 7,399
Записей в блоге: 2
Завершенные тесты: 1
09.02.2012, 07:11  [ТС] #14
Тут похоже дело в производительности компьютера. Думаю если с фортраном сравнить, то разница тоже хорошая будет.
0
ForEveR
В астрале
Эксперт С++
7985 / 4744 / 321
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
09.02.2012, 10:21 #15
C++.
Стандартные опции.
Bash
1
2
3
4
forever@pterois:~/My_pro1/cpp_pro$ g++ -o new new.cpp -std=c++0x -lrt
forever@pterois:~/My_pro1/cpp_pro$ ./new 
Start calculation...
Time calculation: 20,472700106
O1.
Bash
1
2
3
4
forever@pterois:~/My_pro1/cpp_pro$ g++ -o new new.cpp -std=c++0x -lrt -O1
forever@pterois:~/My_pro1/cpp_pro$ ./new 
Start calculation...
Time calculation: 17,44365911
O2.
Bash
1
2
3
4
forever@pterois:~/My_pro1/cpp_pro$ g++ -o new new.cpp -std=c++0x -lrt -O2
forever@pterois:~/My_pro1/cpp_pro$ ./new 
Start calculation...
Time calculation: 16,436316937
O3.
Bash
1
2
3
4
forever@pterois:~/My_pro1/cpp_pro$ g++ -o new new.cpp -std=c++0x -lrt -O3
forever@pterois:~/My_pro1/cpp_pro$ ./new 
Start calculation...
Time calculation: 17,568185084
Fortran.
O0.
Bash
1
2
3
4
forever@pterois:~/My_pro1/cpp_pro$ gfortran -o fort fort.f95 -O0
forever@pterois:~/My_pro1/cpp_pro$ ./fort 
 Start calculation...
 Time calculation:    88.117508
O1.
Bash
1
2
3
4
forever@pterois:~/My_pro1/cpp_pro$ gfortran -o fort fort.f95 -O1
forever@pterois:~/My_pro1/cpp_pro$ ./fort 
 Start calculation...
 Time calculation:    74.132637
O2.
Bash
1
2
3
4
forever@pterois:~/My_pro1/cpp_pro$ gfortran -o fort fort.f95 -O2
forever@pterois:~/My_pro1/cpp_pro$ ./fort 
 Start calculation...
 Time calculation:    73.540596
O3.
Bash
1
2
3
4
forever@pterois:~/My_pro1/cpp_pro$ gfortran -o fort fort.f95 -O3
forever@pterois:~/My_pro1/cpp_pro$ ./fort 
 Start calculation...
 Time calculation:    73.912621
1
09.02.2012, 10:21
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
09.02.2012, 10:21
Привет! Вот еще темы с ответами:

Код, написанный на Borland C++ не работает в Dev C++ - C++
программа на Си++ пользуюсь DEV-CPP Не могу разобраться почему не работает программа. Если у кого есть время помогите пожалуйста. ...

Код для консоли, написанный в RAD XE7, не работает на VS2013 - C++
Программа создает односвязный список структур. Данные в структуру считываются из текстового файла. Программу начал писать в RAD, работает...

Определить, сколько элементов между самым большим отрицательным числом и самым маленьким положительным - C++
Подскажите в чем проблема! Код определяет самое большое отрицательное число и самое маленькое положительное число, НО не отрабатывает...

Определить,сколько элементов массива располагается между самым большим и самым маленьким элементами являющимися простыми числами - C++
Определить,сколько элементов массива располагается между самым большим и самым маленьким элементами являющимися простыми числами:wall:


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.