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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
kozlik_kozlik
7 / 11 / 0
Регистрация: 01.08.2012
Сообщений: 99
#1

Что быстрее? Обращение к элементу массива или к элементу структуры? - C++

14.07.2015, 22:54. Просмотров 546. Ответов 16
Метки нет (Все метки)

Обращение к элементу массива или к элементу структуры?
Экспериментирую с кодом и получается примерно одинаково. Что интересно, время на вызов функции do_nothing получилось примерно такое же. Оптимизация отключена.

Верен ли вывод, что обращение к элементу массива, элементу структуры и вызов функции занимают одинаковое время?

Использую MinGW 4.4 с Qt 4.7.4.

C++ (Qt)
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
#include <iostream>
#include <ctime>
 
using namespace std;
 
struct st
{
    int a, b;
    int c;
};
 
void do_nothing() {}
 
int main()
{
    int x[10]={0};
    st s;
    s.a=5; s.b=4; s.c=12;
 
    int y=0;
 
    int t0=clock();
 
    for (int i=0; i<=100000000; i++)
    {
        //y=x[5];
        y=s.c;
        //do_nothing();
    }
 
    int t1=clock();
 
    cout << "ticks=" << t1-t0 << "\t" << endl;
 
    cout << "Hello World!" << endl;
    return 0;
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
14.07.2015, 22:54
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Что быстрее? Обращение к элементу массива или к элементу структуры? (C++):

Обращение к элементу массива - C++
Объясните пожалуйста, что происходит в строке помеченной *** void main(){ char str; char ptr; cin &gt;&gt; str; cout &lt;&lt; ...

Обращение к элементу массива - C++
Как мне обратиться к последнему элементу массива? например: Array // i = 0 тут нужно что бы -1 был последним т.е N-1 //можно ли с...

Обращение к элементу массива из строк - C++
Здравствуйте! Имеется такой код: string mesiaci = //Massiv iz strok { &quot;Ianvar'&quot;, &quot;Fevral'&quot;, &quot;Mart&quot;, &quot;Aprel'&quot;, ...

Map iterator обращение к предыдущему или последующему элементу - C++
for(map&lt;string,int&gt;::iterator i = m.begin();i!=m.end();i++) if( (i+1) == m.end() ) cout &lt;&lt; &quot;End&quot;; Как сделать что-то...

Обращение к элементу массива через адрес - C++
#include &quot;a.h&quot; #include &lt;iostream&gt; #include&lt;stdio.h&gt; using namespace std; void vvod(float mas,int n); void calc(float...

Организовать обращение к элементу массива в классе - C++
Есть класс: class Graf { public: double **M; double MT; Graf(){}; ~Graf(){}; Graf(int n){

16
Croessmah
Эксперт CЭксперт С++
13413 / 7564 / 855
Регистрация: 27.09.2012
Сообщений: 18,618
Записей в блоге: 3
Завершенные тесты: 1
14.07.2015, 23:08 #2
Цитата Сообщение от kozlik_kozlik Посмотреть сообщение
Использую MinGW 4.4
опции компилятора какие?
Вот то, что получилось из Вашего цикла при O3:
Assembler
1
2
3
    call    clock
    movq    %rax, %rbp
    call    clock
Как видите, цикл просто вырезали.
0
Evg
Эксперт CАвтор FAQ
17934 / 6162 / 409
Регистрация: 30.03.2009
Сообщений: 16,918
Записей в блоге: 27
14.07.2015, 23:15 #3
Цитата Сообщение от kozlik_kozlik Посмотреть сообщение
Обращение к элементу массива или к элементу структуры?
В общем случае одинаково при условии, что обращение к элементу массива делается с константными индексами. В обоих случаях читается значение из "адрес объекта плюс константное смещение". В частном случае нужно учитывать, что для некоторых машин начинает играть роль конкретное значение смещения из-за того, что короткие литералы (константы) можно закодировать прямо в операции, а длинные константы требуют пересылки на регистр. Т.е. при сравнении нужно проверять, чтобы обращение было по одинаковому байтовому смещению

Код по проведению эксперимента, очевидно, неправильный. Да и эксперименты нужно проводить в режиме с оптимизациями, потому что в режиме без оптимизации ты будешь замерять особенности работы компилятора, а вовсе не полученный код
0
kozlik_kozlik
7 / 11 / 0
Регистрация: 01.08.2012
Сообщений: 99
14.07.2015, 23:16  [ТС] #4
опции компилятора какие?
O0

Код по проведению эксперимента, очевидно, неправильный
Чем?
0
Evg
Эксперт CАвтор FAQ
17934 / 6162 / 409
Регистрация: 30.03.2009
Сообщений: 16,918
Записей в блоге: 27
14.07.2015, 23:19 #5
Да и сам код для замеров нужно правильно строить. При том коде, который написан, условные 70% (хз сколько в точности, может и больше) будут занимать накладные расходы по организации цикла, и только оставшиеся условные 30% - сам полезный код, который хочется замерить

Добавлено через 56 секунд
Цитата Сообщение от kozlik_kozlik Посмотреть сообщение
Чем?
Выше написано. В посте #2 показано, что будет при работе оптимизаций. В посте #3 написано, что ты вообще замеришь без оптимизаций. Как минимум этих двух пунктов достаточно
0
kozlik_kozlik
7 / 11 / 0
Регистрация: 01.08.2012
Сообщений: 99
14.07.2015, 23:24  [ТС] #6
При том коде, который написан, условные 70% (хз сколько в точности, может и больше) будут занимать накладные расходы по организации цикла, и только оставшиеся условные 30% - сам полезный код, который хочется замерить
Большая разница будет видна.

Как организовать код, чтобы в замер попало больше времени в % от полезного кода?

В посте #3 написано, что ты вообще замеришь без оптимизаций
Мне важно посмотреть именно без оптимизаций.
0
Evg
Эксперт CАвтор FAQ
17934 / 6162 / 409
Регистрация: 30.03.2009
Сообщений: 16,918
Записей в блоге: 27
15.07.2015, 09:30 #7
Цитата Сообщение от kozlik_kozlik Посмотреть сообщение
Как организовать код, чтобы в замер попало больше времени в % от полезного кода?
Например, внутри цикла 10 раз повторить интересующую тебя операцию. Ну а в реальной жизни никто не занимается такими вещами, как измерение скорости работы одной операции языка. Для этого всегда можно посмотреть код и почитать систему команд

Цитата Сообщение от kozlik_kozlik Посмотреть сообщение
Мне важно посмотреть именно без оптимизаций
Да смотри ради бога. Но понимай при этом, что ты измеряешь попугаев, а не скорость кода
0
Croessmah
Эксперт CЭксперт С++
13413 / 7564 / 855
Регистрация: 27.09.2012
Сообщений: 18,618
Записей в блоге: 3
Завершенные тесты: 1
15.07.2015, 09:46 #8
Да и вызов функции понятие достаточно толстое.
С одной стороны - это просто "прыжок" в коде, но ведь к данному прыжку нужно подготовиться. Положить что куда нужно, сохранить что нужно. А назад мы придем только когда фукция завершится, а это опять "пыжок", "укладка", восстановление. Всё это накладные расходы, которые прибавятся к расходам на сам вызов (прыжок).

Добавлено через 6 минут
Evg, 70% на 30%? Так здесь в эти 30% еще и присваивание войдет, так что можно снижать минимум вдвое.
0
Evg
Эксперт CАвтор FAQ
17934 / 6162 / 409
Регистрация: 30.03.2009
Сообщений: 16,918
Записей в блоге: 27
15.07.2015, 11:43 #9
Цитата Сообщение от Croessmah Посмотреть сообщение
Evg, 70% на 30%? Так здесь в эти 30% еще и присваивание войдет, так что можно снижать минимум вдвое
Для присваивания как такового отдельной операции нет. Есть load, который одновременно читает из памяти и пишет в регистр. Т.е. он сразу же делает и присваивание. В своей оценке я исходил из того, что счётчик цикла и переменная y (которая там нафиг не нужна) располагаются на регистрах, а массив или структура - в памяти. Обращение в память - длинная операция с точки зрения процессора, а потому она имеет бОльший вес, чем какая-либо другая арифметическая операция из обслуживающего цикла. Переход назад в длинном цикле будет работать быстро (т.к. предсказатель переходов на intele очень быстро настроится)
1
Croessmah
Эксперт CЭксперт С++
13413 / 7564 / 855
Регистрация: 27.09.2012
Сообщений: 18,618
Записей в блоге: 3
Завершенные тесты: 1
15.07.2015, 12:10 #10
Evg, ну лично у меня, с -O0, вылилось в
Assembler
1
2
    movl    -44(%ebp), %eax
    movl    %eax, -32(%ebp)
По сути, нас интересует только первая операция, вторая - это уже пихание результата в y
0
Evg
Эксперт CАвтор FAQ
17934 / 6162 / 409
Регистрация: 30.03.2009
Сообщений: 16,918
Записей в блоге: 27
15.07.2015, 13:21 #11
Цитата Сообщение от Croessmah Посмотреть сообщение
Evg, ну лично у меня, с -O0, вылилось в
Потому что "y" распределился в стеке, а не на регистре. Кстати, наглядная демонстрация того, что тест меряет не то, что надо

Добавлено через 33 секунды
Точнее, не тест, а его запуск в режиме без оптимизаций
1
VD
23 / 12 / 2
Регистрация: 02.08.2012
Сообщений: 150
16.07.2015, 21:37 #12
Обращение к массиву:
y=x[5];
Assembler
1
2
3
4
    mov eax, 4
    imul    ecx, eax, 5
    mov edx, DWORD PTR _x$[ebp+ecx]
    mov DWORD PTR _y$[ebp], edx
Обращение к структуре:
y = s.c;
Assembler
1
2
    mov eax, DWORD PTR _s$[ebp+8]
    mov DWORD PTR _y$[ebp], eax
Вот так генерирует VS2013.
Из чего вроде как бы следует что обращение к структуре быстрее.
0
Renji
1925 / 1323 / 298
Регистрация: 05.06.2014
Сообщений: 3,808
16.07.2015, 21:46 #13
Цитата Сообщение от VD Посмотреть сообщение
Вот так генерирует VS2013.
Плохо генерирует. В вашем коде imul умножает четыре на пять. То есть, константу на константу. Результат такого умножения можно посчитать на стадии компиляции, а imul выкинуть за ненадобностью.
А вот если индекс элемента массива заранее неизвестен, тогда да, обращение к элементу будет медленнее обращения к элементу структуры.
0
VD
23 / 12 / 2
Регистрация: 02.08.2012
Сообщений: 150
16.07.2015, 21:53 #14
Renji, у точно и правда можно выкинуть. И зачем же компилятор так делает...
0
Evg
Эксперт CАвтор FAQ
17934 / 6162 / 409
Регистрация: 30.03.2009
Сообщений: 16,918
Записей в блоге: 27
16.07.2015, 21:54 #15
Цитата Сообщение от VD Посмотреть сообщение
И зачем же компилятор так делает
Потому что оптимизации не включены
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
16.07.2015, 21:54
Привет! Вот еще темы с ответами:

Обращение к элементу динамического массива структур - C++
Само задание: http://cs412722.vk.me/v412722398/4e77/fUkq93u2HDE.jpg пока написал только это: #include &lt;iostream&gt; using namespace std;...

Обращение ко второму элементу массива указателей на строки - C++
Добрый день. Не получается обратиться ко второму элементу: #include &lt;stdio.h&gt; int main(void) { char **ss = { &quot;Run away&quot;, ...

Обращение к элементу массива (массив как поле класса) - C++
есть класс с массивом class ArrayPixel { public: byte*** pixel; ArrayPixel(int, int); ~ArrayPixel(void); private:

Задача Таблица. За одно обращение к каждому элементу массива необходимо каждый элемент заменить ближайшим большим следующим за ним - C++
Не могу решить задачу( В массиве А размера n за одно обращение к каждому элементу массива необходимо каждый элемент заменить ближайшим ...


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

Или воспользуйтесь поиском по форуму:
15
Yandex
Объявления
16.07.2015, 21:54
Ответ Создать тему
Опции темы

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