Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.83/6: Рейтинг темы: голосов - 6, средняя оценка - 4.83
 Аватар для mat_for_c
223 / 213 / 80
Регистрация: 26.04.2013
Сообщений: 972

Объяснить нюансы оптимизации заданного фрагмента кода

28.09.2016, 00:36. Показов 1218. Ответов 11
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Наткнулся на статью по оптимизации кода на C++http://itw66.ru/blog/c_plus_plus/13.html]ссылка
Есть там 10-й пункт:
C++
1
2
3
SomeClass* p; - указатель на массив элементов
x = *(p++); - значительно эффективнее
x = *(++p);
По той же причине что и пункт 1. В первом случае будет осуществляться разыменование указателя и его инкремент параллельно, а во втором — последовательно.

Пункт 1:
Используйте векторизацию данных и векторные команды их обработки (например SSE в CPU или упаковывайте данные если используете шейдеры или CUDA). Это позволит использовать SIMD (Single Instruction, Multiple Data) архитектуру, что значительно повысит скорость вычислений. Если вы решите использовать этот метод, то не забывайте про выравнивание данных в памяти.

Может кто объяснить, почему инкремент и разыменование будут происходить параллельно?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
28.09.2016, 00:36
Ответы с готовыми решениями:

Считывание структуры из файла: объяснить нюансы работы кода
есть функция, которая должна из файла считывать значения полей элементов массива структур и инициализировать эти поля этими значениями, но...

Нюансы синтаксиса: объяснить, что происходит в заданных участках кода
mas_tops=new node *; // что это строка значит? и зачем она нужна create_massiv_of_lists(node** x,int l) // зачем тут двойной указатель ...

Нюансы синтаксиса: объяснить что происходит в заданных строках кода
Разбираюсь со структурами. Подскажите, пожалуйста, что означает с 3 по 7 строку? Для чего так делается? struct node { ...

11
331 / 283 / 78
Регистрация: 02.08.2016
Сообщений: 1,008
28.09.2016, 02:11
а ничего, что эти выражения дают разный результат? И я себе не могу представить, как на одном ядре может параллельно разыменовываться и инкрементироваться указатель, да и на нескольких ядрах вряд ли.

Добавлено через 18 минут
вот какая между ними разница на асме:
Если я ничего не напутал, то вот это x = *(p++);
Assembler
1
2
3
mov     rax, QWORD PTR [rbp-8]
lea     rdx, [rax+4]
mov     QWORD PTR [rbp-8], rdx
а это x = *(++p);
Assembler
1
2
add     QWORD PTR [rbp-8], 4
mov     rax, QWORD PTR [rbp-8]
Остальные строки полностью идентичны. Про эффективность ничего не скажу, не гуру ассемблера.

Добавлено через 6 минут
Если я ничего не напутал, то вот это x = *(p++);
Assembler
1
2
3
mov     rax, QWORD PTR [rbp-8]; записываем значение указателя в регистр
lea     rdx, [rax+4]; вычисляем адрес, который только что записали плюс четыре байта, результат в rdx 
mov     QWORD PTR [rbp-8], rdx; полученное значение записываем туда где хранится значение указателя
а это x = *(++p);
Assembler
1
2
add     QWORD PTR [rbp-8], 4; инкрементируем указатель
mov     rax, QWORD PTR [rbp-8]; записываем значение указателя в регистр
1
 Аватар для ASCII
99 / 70 / 13
Регистрация: 15.12.2013
Сообщений: 463
28.09.2016, 09:48
DevAlone, Эти Ваши 5 строк ни о чем не говорят, ибо нету С++ кода, для которого Вы получили этот дисасм.

А по теме: странное какое-то утверждение.
0
Helper C/C++
 Аватар для Invader0x7F
286 / 163 / 122
Регистрация: 22.09.2016
Сообщений: 518
28.09.2016, 09:56
А вы уверены что код на С++:

C++
1
2
3
SomeClass* p; - указатель на массив элементов
x = *(p++); - значительно эффективнее
x = *(++p);
в точности соответствует приведенным дизасмам ??
0
331 / 283 / 78
Регистрация: 02.08.2016
Сообщений: 1,008
28.09.2016, 18:14
Цитата Сообщение от ASCII Посмотреть сообщение
DevAlone, Эти Ваши 5 строк ни о чем не говорят, ибо нету С++ кода, для которого Вы получили этот дисасм.
Цитата Сообщение от Invader0x7F Посмотреть сообщение
А вы уверены что код на С++:
C++
1
2
3
SomeClass* p; - указатель на массив элементов
x = *(p++); - значительно эффективнее
x = *(++p);
в точности соответствует приведенным дизасмам ??
Забыл скинуть. Код был такой:
C++
1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
 
int main()
{
 int array[] = {5, 2};
 int *p = &array[0];
 int x;
 //x = *(p++);// первый вариант
 x = *(++p);// второй
 std::cout << x << std::endl;
 return 0;
}
1
Helper C/C++
 Аватар для Invader0x7F
286 / 163 / 122
Регистрация: 22.09.2016
Сообщений: 518
28.09.2016, 18:15
Вы бы лучше своими силами программу С++ на Ассемблер перевели, и тогда всем было бы все ясно.
0
331 / 283 / 78
Регистрация: 02.08.2016
Сообщений: 1,008
28.09.2016, 18:56
Первая:

Assembler
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
86
87
88
89
90
91
92
        .file   "main.cpp"
        .intel_syntax noprefix
        .local  _ZStL8__ioinit
        .comm   _ZStL8__ioinit,1,1
        .text
        .globl  main
        .type   main, @function
main:
.LFB1020:
        .cfi_startproc
        push    rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        mov     rbp, rsp
        .cfi_def_cfa_register 6
        sub     rsp, 32
        mov     DWORD PTR [rbp-32], 5
        mov     DWORD PTR [rbp-28], 2
        lea     rax, [rbp-32]
        mov     QWORD PTR [rbp-8], rax
        mov     rax, QWORD PTR [rbp-8]      ;
        lea     rdx, [rax+4]            ;
        mov     QWORD PTR [rbp-8], rdx      ;
        mov     eax, DWORD PTR [rax]
        mov     DWORD PTR [rbp-12], eax
        mov     eax, DWORD PTR [rbp-12]
        mov     esi, eax
        mov     edi, OFFSET FLAT:_ZSt4cout
        call    _ZNSolsEi
        mov     esi, OFFSET FLAT:_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
        mov     rdi, rax
        call    _ZNSolsEPFRSoS_E
        mov     eax, 0
        leave
        .cfi_def_cfa 7, 8
        ret
        .cfi_endproc
.LFE1020:
        .size   main, .-main
        .type   _Z41__static_initialization_and_destruction_0ii, @function
_Z41__static_initialization_and_destruction_0ii:
.LFB1026:
        .cfi_startproc
        push    rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        mov     rbp, rsp
        .cfi_def_cfa_register 6
        sub     rsp, 16
        mov     DWORD PTR [rbp-4], edi
        mov     DWORD PTR [rbp-8], esi
        cmp     DWORD PTR [rbp-4], 1
        jne     .L3
        cmp     DWORD PTR [rbp-8], 65535
        jne     .L3
        mov     edi, OFFSET FLAT:_ZStL8__ioinit
        call    _ZNSt8ios_base4InitC1Ev
        mov     edx, OFFSET FLAT:__dso_handle
        mov     esi, OFFSET FLAT:_ZStL8__ioinit
        mov     edi, OFFSET FLAT:_ZNSt8ios_base4InitD1Ev
        call    __cxa_atexit
.L3:
        leave
        .cfi_def_cfa 7, 8
        ret
        .cfi_endproc
.LFE1026:
        .size   _Z41__static_initialization_and_destruction_0ii, .-_Z41__static_initialization_and_destruction_0ii
        .type   _GLOBAL__sub_I_main, @function
_GLOBAL__sub_I_main:
.LFB1027:
        .cfi_startproc
        push    rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        mov     rbp, rsp
        .cfi_def_cfa_register 6
        mov     esi, 65535
        mov     edi, 1
        call    _Z41__static_initialization_and_destruction_0ii
        pop     rbp
        .cfi_def_cfa 7, 8
        ret
        .cfi_endproc
.LFE1027:
        .size   _GLOBAL__sub_I_main, .-_GLOBAL__sub_I_main
        .section        .init_array,"aw"
        .align 8
        .quad   _GLOBAL__sub_I_main
        .hidden __dso_handle
        .ident  "GCC: (Debian 4.9.2-10) 4.9.2"
        .section        .note.GNU-stack,"",@progbits
Вторая:
Assembler
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
86
87
88
89
90
91
        .file   "main.cpp"
        .intel_syntax noprefix
        .local  _ZStL8__ioinit
        .comm   _ZStL8__ioinit,1,1
        .text
        .globl  main
        .type   main, @function
main:
.LFB1020:
        .cfi_startproc
        push    rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        mov     rbp, rsp
        .cfi_def_cfa_register 6
        sub     rsp, 32
        mov     DWORD PTR [rbp-32], 5
        mov     DWORD PTR [rbp-28], 2
        lea     rax, [rbp-32]
        mov     QWORD PTR [rbp-8], rax
        add     QWORD PTR [rbp-8], 4        ;
        mov     rax, QWORD PTR [rbp-8]      ;
        mov     eax, DWORD PTR [rax]
        mov     DWORD PTR [rbp-12], eax
        mov     eax, DWORD PTR [rbp-12]
        mov     esi, eax
        mov     edi, OFFSET FLAT:_ZSt4cout
        call    _ZNSolsEi
        mov     esi, OFFSET FLAT:_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
        mov     rdi, rax
        call    _ZNSolsEPFRSoS_E
        mov     eax, 0
        leave
        .cfi_def_cfa 7, 8
        ret
        .cfi_endproc
.LFE1020:
        .size   main, .-main
        .type   _Z41__static_initialization_and_destruction_0ii, @function
_Z41__static_initialization_and_destruction_0ii:
.LFB1026:
        .cfi_startproc
        push    rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        mov     rbp, rsp
        .cfi_def_cfa_register 6
        sub     rsp, 16
        mov     DWORD PTR [rbp-4], edi
        mov     DWORD PTR [rbp-8], esi
        cmp     DWORD PTR [rbp-4], 1
        jne     .L3
        cmp     DWORD PTR [rbp-8], 65535
        jne     .L3
        mov     edi, OFFSET FLAT:_ZStL8__ioinit
        call    _ZNSt8ios_base4InitC1Ev
        mov     edx, OFFSET FLAT:__dso_handle
        mov     esi, OFFSET FLAT:_ZStL8__ioinit
        mov     edi, OFFSET FLAT:_ZNSt8ios_base4InitD1Ev
        call    __cxa_atexit
.L3:
        leave
        .cfi_def_cfa 7, 8
        ret
        .cfi_endproc
.LFE1026:
        .size   _Z41__static_initialization_and_destruction_0ii, .-_Z41__static_initialization_and_destruction_0ii
        .type   _GLOBAL__sub_I_main, @function
_GLOBAL__sub_I_main:
.LFB1027:
        .cfi_startproc
        push    rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        mov     rbp, rsp
        .cfi_def_cfa_register 6
        mov     esi, 65535
        mov     edi, 1
        call    _Z41__static_initialization_and_destruction_0ii
        pop     rbp
        .cfi_def_cfa 7, 8
        ret
        .cfi_endproc
.LFE1027:
        .size   _GLOBAL__sub_I_main, .-_GLOBAL__sub_I_main
        .section        .init_array,"aw"
        .align 8
        .quad   _GLOBAL__sub_I_main
        .hidden __dso_handle
        .ident  "GCC: (Debian 4.9.2-10) 4.9.2"
        .section        .note.GNU-stack,"",@progbits
1
 Аватар для Voivoid
710 / 283 / 16
Регистрация: 31.03.2013
Сообщений: 1,340
28.09.2016, 21:08
Цитата Сообщение от mat_for_c Посмотреть сообщение
Наткнулся на статью по оптимизации кода на C++
Так себе статейка, лет 15 назад еще была актуальна, но сейчас многое устарело

Цитата Сообщение от mat_for_c Посмотреть сообщение
Есть там 10-й пункт:
Пункт в целом бесполезный и высосан из пальца

Цитата Сообщение от mat_for_c Посмотреть сообщение
Может кто объяснить, почему инкремент и разыменование будут происходить параллельно?
Читай про конвееры процессора
2
42 / 42 / 17
Регистрация: 25.04.2014
Сообщений: 499
29.09.2016, 02:36
Voivoid, киданите плз новье какое-нибудь
0
Неэпический
 Аватар для Croessmah
18144 / 10728 / 2066
Регистрация: 27.09.2012
Сообщений: 27,028
Записей в блоге: 1
29.09.2016, 05:12
Влияние конвейера на скорость исполнения кода
3
 Аватар для Voivoid
710 / 283 / 16
Регистрация: 31.03.2013
Сообщений: 1,340
29.09.2016, 09:20
Цитата Сообщение от tapochka Посмотреть сообщение
Voivoid, киданите плз новье какое-нибудь
по выскоуровневым оптимизациям - http://shop.oreilly.com/product/0636920038030.do
по низкоуровневым - http://www.agner.org/optimize/
4
42 / 42 / 17
Регистрация: 25.04.2014
Сообщений: 499
30.09.2016, 23:18
Voivoid, вторая ссылка годная имхо, благодарствую
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
30.09.2016, 23:18
Помогаю со студенческими работами здесь

Нюансы работы с указателями: объяснить, что происходит в заданном фрагменте кода
Всем доброго времени суток! Я не до конца разобрался в данной теме. К примеру, есть такой кусок программы: ... int N; int...

Нюансы синтаксиса: объяснить как работает тернарная операция в заданном фрагменте кода
Всем доброго времени суток! Помогите разобраться с кодом. const char x = {&quot;Jason &quot;, &quot;at your service\n&quot;}; const char * y =...

Нюансы синтаксиса: объяснить использование ключевого слова typedef в заданном фрагменте кода
Всем привет. Недавно на просторах интернета столкнулся с таким кодом: typedef double(*pointFunc)(double); double f(double x) { ...

Найти объём усечённого конуса методом Монте-Карло (объяснить нюансы работы кода)
В примере ниже вычисляется методом монте-карло объем усеченного конуса, накрытого полусферой. Объем такого тела вычисляется по формуле: ...

Нюансы синтаксиса: объяснить что происходит в заданных строках кода и для чего нужны указанные конструкции
Наткнулся на урок по C++ в интернете, где был пример с перебором &quot;телефонной книги&quot;. Вот кусок кода, где объявляется класс: class...


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

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Новые блоги и статьи
Использование SDL3-callbacks вместо функции main() на Android, Desktop и WebAssembly
8Observer8 24.01.2026
Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а привычная функция main(). . .
моя боль
iceja 24.01.2026
Выложила интерполяцию кубическими сплайнами www. iceja. net REST сервисы временно не работают, только через Web. Написала за 56 рабочих часов этот сайт с нуля. При помощи perplexity. ai PRO , при. . .
Модель сукцессии микоризы
anaschu 24.01.2026
Решили писать научную статью с неким РОманом
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь(не выше 3-го порядка) постоянного тока с элементами R, L, C, k(ключ), U, E, J. Программа находит переходные токи и напряжения на элементах схемы классическим методом(1 и 2 з-ны. . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru