Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.82/11: Рейтинг темы: голосов - 11, средняя оценка - 4.82
9 / 9 / 9
Регистрация: 19.09.2011
Сообщений: 272

Инлайн-функция замедляет работу

11.04.2013, 16:12. Показов 2204. Ответов 16
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте! видимо что-то делаю неправильно...имею код. Запускаю скомпилированную программу - работает с одной скоростью. Копипастю код в инлайн функцию - скорость выполнения резко уменьшается.
если кому интересно - вот начальный код
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
// Task3.cpp: определяет точку входа для консольного приложения.
//
 
#include <stdlib.h>
#include <math.h>
#include <sys/time.h>
#include <iostream>
#include <omp.h>
 
using namespace std;
 
 
int main(int argc, char **argv)
{
    int threads = atoi(argv[2]);
    int n = atoi(argv[1]);
    
 
//Задание 2
    struct timeval StartTime;
    struct timeval EndTime;
    
    double* result = new double[n*n];
    double* A = new double[n*n];
    double* B = new double[n*n];
 
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            result[i*n+j] = 0;
 
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            A[i*n+j] = i+1;
 
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            B[i*n+j] = 1.0/(j+1);
    int i,k;
    double *indres,*indA,*indB,*ind1B,*ind2B,*ind3B,*ind4B,*ind5B,*ind6B,*ind7B,*ind8B,*ind9B;
    gettimeofday(&StartTime,NULL);
 
#pragma omp parallel num_threads(threads) private(i,k,indres,indA,indB,ind1B,ind2B,ind3B,ind4B,ind5B,ind6B,ind7B,ind8B,ind9B) shared(result,A,B)
    {
#pragma omp for schedule(dynamic,25)
        for ( i = 0; i < n; i++)
    {
        indB = B;
        ind1B = B+n;
        ind2B = ind1B+n;
        ind3B = ind2B+n;
        ind4B = ind3B+n;
        ind5B = ind4B+n;
        ind6B = ind5B+n;
        ind7B = ind6B+n;
        ind8B = ind7B+n;
        ind9B = ind8B+n;
        indA = A+i*n;
        for(k =0; k < n; k+=10)
        {
            double *endres = result+(i+1)*n;
            for ( indres = result+i*n; indres < endres; indB+=5, ind1B+=5,ind2B+=5,ind3B+=5,ind4B+=5,ind5B+=5,ind6B+=5,ind7B+=5,ind8B+=5,ind9B+=5 ,indres+=5 )
            {
                indres[0] += indA[k] * indB[0];
                indres[1] += indA[k] * indB[1];
                indres[2] += indA[k] * indB[2];
                indres[3] += indA[k] * indB[3];
                indres[4] += indA[k] * indB[4];
                
                indres[0] += indA[k+1] * ind1B[0];
                indres[1] += indA[k+1] * ind1B[1];
                indres[2] += indA[k+1] * ind1B[2];
                indres[3] += indA[k+1] * ind1B[3];
                indres[4] += indA[k+1] * ind1B[4];
                
                indres[0] += indA[k+2] * ind2B[0];
                indres[1] += indA[k+2] * ind2B[1];
                indres[2] += indA[k+2] * ind2B[2];
                indres[3] += indA[k+2] * ind2B[3];
                indres[4] += indA[k+2] * ind2B[4];
                
                indres[0] += indA[k+3] * ind3B[0];
                indres[1] += indA[k+3] * ind3B[1];
                indres[2] += indA[k+3] * ind3B[2];
                indres[3] += indA[k+3] * ind3B[3];
                indres[4] += indA[k+3] * ind3B[4];
                
                indres[0] += indA[k+4] * ind4B[0];
                indres[1] += indA[k+4] * ind4B[1];
                indres[2] += indA[k+4] * ind4B[2];
                indres[3] += indA[k+4] * ind4B[3];
                indres[4] += indA[k+4] * ind4B[4];
                //
                indres[0] += indA[k+5] * ind5B[0];
                indres[1] += indA[k+5] * ind5B[1];
                indres[2] += indA[k+5] * ind5B[2];
                indres[3] += indA[k+5] * ind5B[3];
                indres[4] += indA[k+5] * ind5B[4];
                
                indres[0] += indA[k+6] * ind6B[0];
                indres[1] += indA[k+6] * ind6B[1];
                indres[2] += indA[k+6] * ind6B[2];
                indres[3] += indA[k+6] * ind6B[3];
                indres[4] += indA[k+6] * ind6B[4];
                
                indres[0] += indA[k+7] * ind7B[0];
                indres[1] += indA[k+7] * ind7B[1];
                indres[2] += indA[k+7] * ind7B[2];
                indres[3] += indA[k+7] * ind7B[3];
                indres[4] += indA[k+7] * ind7B[4];
                
                indres[0] += indA[k+8] * ind8B[0];
                indres[1] += indA[k+8] * ind8B[1];
                indres[2] += indA[k+8] * ind8B[2];
                indres[3] += indA[k+8] * ind8B[3];
                indres[4] += indA[k+8] * ind8B[4];
                
                indres[0] += indA[k+9] * ind9B[0];
                indres[1] += indA[k+9] * ind9B[1];
                indres[2] += indA[k+9] * ind9B[2];
                indres[3] += indA[k+9] * ind9B[3];
                indres[4] += indA[k+9] * ind9B[4];
            }
            indB+=9*n;
            ind1B+=9*n;
            ind2B+=9*n;
            ind3B+=9*n;
            ind4B+=9*n;
            
            ind5B+=9*n;
            ind6B+=9*n;
            ind7B+=9*n;
            ind8B+=9*n;
            ind9B+=9*n;
        }
    }
    }
    gettimeofday(&EndTime,NULL);
    double time = (EndTime.tv_sec - StartTime.tv_sec) + (EndTime.tv_usec-StartTime.tv_usec)/1000000.0;
 
    cout<<"Time - "<<fixed<<time<<" sec"<<endl;
 
    cout<<"Perfomance - "<<fixed<<2*((double)n/time)*((double)n*(double)n/1000000.0)<<" MegaFlops\n";
    cout<<fixed<<result[0];
    cout<<fixed<<"\t"<<result[n-1]<<endl;
    cout<<fixed<<result[(n-1)*n];
    cout<<fixed<<"\t"<<result[(n-1)*n+n-1]<<endl;
    cout<<"Threads count = "<<threads<<endl;
    
        delete[] result;
        delete[] A;
        delete[] B;
//Задание 2
    return 0;       
}
А это уже вставленный в функцию
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
// Task3.cpp: определяет точку входа для консольного приложения.
//
 
#include <stdlib.h>
#include <math.h>
#include <sys/time.h>
#include <iostream>
#include <omp.h>
 
using namespace std;
 
inline void Mult(double *A, double *B, double *result)
{
int i,k,n=500;
int threads = 1;
    double *indres,*indA,*indB,*ind1B,*ind2B,*ind3B,*ind4B,*ind5B,*ind6B,*ind7B,*ind8B,*ind9B;
 
#pragma omp parallel num_threads(threads) firstprivate(n) private(i,k,indres,indA,indB,ind1B,ind2B,ind3B,ind4B,ind5B,ind6B,ind7B,ind8B,ind9B) shared(result,A,B)
    {
#pragma omp for schedule(dynamic,25)
        for ( i = 0; i < n; i++)
    {
        indB = B;
        ind1B = B+n;
        ind2B = ind1B+n;
        ind3B = ind2B+n;
        ind4B = ind3B+n;
        ind5B = ind4B+n;
        ind6B = ind5B+n;
        ind7B = ind6B+n;
        ind8B = ind7B+n;
        ind9B = ind8B+n;
        indA = A+i*n;
        for(k =0; k < n; k+=10)
        {
            double *endres = result+(i+1)*n;
            for ( indres = result+i*n; indres < endres; indB+=5, ind1B+=5,ind2B+=5,ind3B+=5,ind4B+=5,ind5B+=5,ind6B+=5,ind7B+=5,ind8B+=5,ind9B+=5 ,indres+=5 )
            {
                indres[0] += indA[k] * indB[0];
                indres[1] += indA[k] * indB[1];
                indres[2] += indA[k] * indB[2];
                indres[3] += indA[k] * indB[3];
                indres[4] += indA[k] * indB[4];
                
                indres[0] += indA[k+1] * ind1B[0];
                indres[1] += indA[k+1] * ind1B[1];
                indres[2] += indA[k+1] * ind1B[2];
                indres[3] += indA[k+1] * ind1B[3];
                indres[4] += indA[k+1] * ind1B[4];
                
                indres[0] += indA[k+2] * ind2B[0];
                indres[1] += indA[k+2] * ind2B[1];
                indres[2] += indA[k+2] * ind2B[2];
                indres[3] += indA[k+2] * ind2B[3];
                indres[4] += indA[k+2] * ind2B[4];
                
                indres[0] += indA[k+3] * ind3B[0];
                indres[1] += indA[k+3] * ind3B[1];
                indres[2] += indA[k+3] * ind3B[2];
                indres[3] += indA[k+3] * ind3B[3];
                indres[4] += indA[k+3] * ind3B[4];
                
                indres[0] += indA[k+4] * ind4B[0];
                indres[1] += indA[k+4] * ind4B[1];
                indres[2] += indA[k+4] * ind4B[2];
                indres[3] += indA[k+4] * ind4B[3];
                indres[4] += indA[k+4] * ind4B[4];
                //
                indres[0] += indA[k+5] * ind5B[0];
                indres[1] += indA[k+5] * ind5B[1];
                indres[2] += indA[k+5] * ind5B[2];
                indres[3] += indA[k+5] * ind5B[3];
                indres[4] += indA[k+5] * ind5B[4];
                
                indres[0] += indA[k+6] * ind6B[0];
                indres[1] += indA[k+6] * ind6B[1];
                indres[2] += indA[k+6] * ind6B[2];
                indres[3] += indA[k+6] * ind6B[3];
                indres[4] += indA[k+6] * ind6B[4];
                
                indres[0] += indA[k+7] * ind7B[0];
                indres[1] += indA[k+7] * ind7B[1];
                indres[2] += indA[k+7] * ind7B[2];
                indres[3] += indA[k+7] * ind7B[3];
                indres[4] += indA[k+7] * ind7B[4];
                
                indres[0] += indA[k+8] * ind8B[0];
                indres[1] += indA[k+8] * ind8B[1];
                indres[2] += indA[k+8] * ind8B[2];
                indres[3] += indA[k+8] * ind8B[3];
                indres[4] += indA[k+8] * ind8B[4];
                
                indres[0] += indA[k+9] * ind9B[0];
                indres[1] += indA[k+9] * ind9B[1];
                indres[2] += indA[k+9] * ind9B[2];
                indres[3] += indA[k+9] * ind9B[3];
                indres[4] += indA[k+9] * ind9B[4];
            }
            indB+=9*n;
            ind1B+=9*n;
            ind2B+=9*n;
            ind3B+=9*n;
            ind4B+=9*n;
            
            ind5B+=9*n;
            ind6B+=9*n;
            ind7B+=9*n;
            ind8B+=9*n;
            ind9B+=9*n;
        }
    }
    }
}
 
int main(int argc, char **argv)
{
//Задание 2
    struct timeval StartTime;
    struct timeval EndTime;
    int n=500;
    
    double* result = new double[n*n];
    double* A = new double[n*n];
    double* B = new double[n*n];
 
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            result[i*n+j] = 0;
 
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            A[i*n+j] = i+1;
 
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            B[i*n+j] = 1.0/(j+1);
    
    gettimeofday(&StartTime,NULL);
    Mult(A,B,result);
    gettimeofday(&EndTime,NULL);
    double time = (EndTime.tv_sec - StartTime.tv_sec) + (EndTime.tv_usec-StartTime.tv_usec)/1000000.0;
 
    cout<<"Time - "<<fixed<<time<<" sec"<<endl;
 
    cout<<"Perfomance - "<<fixed<<2*((double)n/time)*((double)n*(double)n/1000000.0)<<" MegaFlops\n";
    cout<<fixed<<result[0];
    cout<<fixed<<"\t"<<result[n-1]<<endl;
    cout<<fixed<<result[(n-1)*n];
    cout<<fixed<<"\t"<<result[(n-1)*n+n-1]<<endl;
    
        delete[] result;
        delete[] A;
        delete[] B;
//Задание 2
    return 0;       
}
Компилятор интеловский. Если замерять время выполнения программы внутри самой функции, то производительность так же оказывается уменьшенной...что не так - понять не могу...первый вариант чуть ли не в 2 раза быстрее работает
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
11.04.2013, 16:12
Ответы с готовыми решениями:

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

Замедляет ли работу программы использование библиотек?
Когда используется библиотеки в коде они как нибудь замедляют работу программы, и при компиляции компилируется вся библиотека или те части...

ООП: Зачем нужна таблица виртуальных методов? Она замедляет работу программы
Разве нельзя определить, метод какого класса вызывать во время компиляции?

16
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
11.04.2013, 16:21
IcyWind, Инлайтить большие функции - это как-то грустно, не находите? К слову, совсем не факт, что функция будет заинлайнена
0
9 / 9 / 9
Регистрация: 19.09.2011
Сообщений: 272
11.04.2013, 17:00  [ТС]
Хорошо. Допустим, что она не инлайнится в функцию мейн. Тогда единственным накладным расходом будет именно вызов этой функции. Тогда всё-равно непонятно! Ведь, когда я замеряю производительность внутри самой функции - то получаю ту же картину - падение производительности примерно в 2 раза
0
 Аватар для Игорь с++
500 / 474 / 63
Регистрация: 26.01.2011
Сообщений: 2,033
11.04.2013, 17:29
вам уже сказали , что инлайнить большие функции нельзя , почитайте про это , да и ещё компилятор видать совсем идиот если даёт это делать.Удачи
0
503 / 352 / 94
Регистрация: 22.03.2011
Сообщений: 1,112
11.04.2013, 17:39
Инлайнить большие функции можно, если нужно. Но есть одно ограничение inline это всего лишь пожелание к компилятору, а не строгое указание. Поэтому он оставляет за собой право встроить или нет (в данном случае нет ибо есть цикл). В вашем случае при инлайне не срабатывает #pragma omp parallel. Если вы знаете с чем работаете читайте маны, если нет, то мой вам совет не трогайте код.
2
9 / 9 / 9
Регистрация: 19.09.2011
Сообщений: 272
11.04.2013, 19:45  [ТС]
Цитата Сообщение от stima Посмотреть сообщение
Инлайнить большие функции можно, если нужно. Но есть одно ограничение inline это всего лишь пожелание к компилятору, а не строгое указание. Поэтому он оставляет за собой право встроить или нет (в данном случае нет ибо есть цикл). В вашем случае при инлайне не срабатывает #pragma omp parallel. Если вы знаете с чем работаете читайте маны, если нет, то мой вам совет не трогайте код.
c OMP я не знаком - знаю только базовые функции и директивы. Читал несколько поверхностных статей + на лекциях тоже в глубины не вдавались - слишком мало часов выделено. Код не получится "не трогать" - стоит учебная задача - вот и пытаюсь разобраться. Про инлайн я знал, что это всего-лишь пожелание.Не смотря на то, что всё обёрнуто в конструкции OMP все тесты пока проводил только на одном потоке. Меня просто поразило то, как резко падала производительность после перевода кода в функцию.
И, кстати, если в функции полностью закомментировать директивы openmp, то производительность нормализуется.
Не подскажете, как обернуть функцию в параллельную секцию? или статьи на эту тему?
и, если есть идеи как ускорить алгоритм, не используя ассемблерные вставки или другие низкоуровневые конструкции, буду очень благодарен) то, что выложил - пока предел моих знаний)
0
 Аватар для Игорь с++
500 / 474 / 63
Регистрация: 26.01.2011
Сообщений: 2,033
11.04.2013, 22:09
Цитата Сообщение от stima Посмотреть сообщение
Инлайнить большие функции можно, если нужно
Покажи мне такого дурака который использует большие инлайн ! И что значит нужно ? Кому нужно ? Приведи реальный хоть один пример когда это обаснованно использовать , и компилятор тебя не пошлёт .

Добавлено через 1 минуту
Цитата Сообщение от Игорь с++ Посмотреть сообщение
нужно
пардон хотел написать - можно
0
503 / 352 / 94
Регистрация: 22.03.2011
Сообщений: 1,112
12.04.2013, 02:37
2Игорь с++ Компилятор меня не пошлет с инлайнами в любом случае, даже при -Wall и -pedantic. Что значит большие инлайны? Сколько строк? Каков их смысл? За примерами смотрите исходники webkita.

2IcyWind Ээээ батюшка да Вы невнимательно копипастите посмотрите на num_tread(), а я та замахнулся на компилятор грешить. Кстате Ваш алгоритм уже оптимизирован оочень сильно в нем учтена оптимизация на уровне инструкций, а это последняя оптимизация распаралеливания.
0
9 / 9 / 9
Регистрация: 19.09.2011
Сообщений: 272
12.04.2013, 02:53  [ТС]
Что-то не могу найти косяк копипаста...вы имеете ввиду это?
Цитата Сообщение от IcyWind Посмотреть сообщение
int threads = 1;
так это специально, чтобы просто на одном потоке проверять.
кстати, я эту всю штуку написал для использования потом в алгоритме блочного перемножения...пока тестил, нашёл ошибку в своей логике...она касается расположения блоков в массиве...
довольно трудно "выцепить" именно тот блок, который мне нужен. Для этого придумал пересчитывать индекс матрицы...при заполнении...чтобы элементы в памяти хранились последовательно по блокам. Таким образом, написанный алгоритм можно не менять нормальное ли это решение? или есть что-нибудь более интересное?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
inline int nind(int ind)
{
    int i = ind / n;
    int j = ind % n;
    return (i/sz)*bl*sz*sz + (j/sz)*sz*sz + (i%sz)*sz + (j%sz);
}
for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            a[nind(i*n+j)] = i+1;
 
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            b[nind(i*n+j)] = 1.0/(j+1);
0
503 / 352 / 94
Регистрация: 22.03.2011
Сообщений: 1,112
12.04.2013, 13:21
А время вы тоже засекали на 1 потоке? Если да, то возможно повлияла синхронизация. Но чтобы точно быть знать, если интересно и есть время, дизассемблируйте обе версии посмотрите в чем разница.
0
Эксперт С++
 Аватар для Avazart
8484 / 6151 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
12.04.2013, 13:47
Цитата Сообщение от IcyWind Посмотреть сообщение
Хорошо. Допустим, что она не инлайнится в функцию мейн. Тогда единственным накладным расходом будет именно вызов этой функции. Тогда всё-равно непонятно! Ведь, когда я замеряю производительность внутри самой функции - то получаю ту же картину - падение производительности примерно в 2 раза
По идее если ф-ция действительно инлайнится то должен быть прирост скорости, а не падение.
А значит дело в другом( ну или это косвенно влияет) ... то есть для чистоты эксперемента уберите распараллеливание.

Вполне возможно что inline мешает работе omp - поэтому проигрыш.
0
9 / 9 / 9
Регистрация: 19.09.2011
Сообщений: 272
12.04.2013, 15:06  [ТС]
Сначала загорелся желанием дизасемблировать...но потом понял, что это надолго...опыта то у меня нет совсем. Поэтому забил. Могу только поделиться впечатлениями. Падение производительности действительно происходит не из-за функции. Но она каким-то образом косвено влияет (в сочетании с openMP). Теперь поясню:
1.)берём код - кидаем в main() - производительность 3.7 Gflops на одном потоке, 6.8 Gflops на двух.
2.)копируем код в инлайн функцию(), передаём туда матрицы через указатели - ну как в коде. Производительность 2 Gflops на одном потоке, 4Gflops на двух.
3.)убираем слово инлайн - аналогично пункту 2
4.)убираем все упоминания об OpenMp в функции - производительность возвращается на уровень 3.7Gflops
0
503 / 352 / 94
Регистрация: 22.03.2011
Сообщений: 1,112
12.04.2013, 16:06
Попробуйте обьявить double *A, double *B, double *result как volatile и лучше мувните их в глобал скоп. Думаю компилятор оптимизирует их.
0
9 / 9 / 9
Регистрация: 19.09.2011
Сообщений: 272
13.04.2013, 08:05  [ТС]
Цитата Сообщение от stima Посмотреть сообщение
Попробуйте обьявить double *A, double *B, double *result как volatile и лучше мувните их в глобал скоп. Думаю компилятор оптимизирует их.
a value of type "volatile double *" cannot be used to initialize an entity of type "double *
не нравится такое компилятору. А вынос в глобал не помогает...если omp parallel вызывать в самой функции, то всё так же падает

Добавлено через 59 секунд
Видимо тогда придётся держать весь код в мейне)
0
 Аватар для taras atavin
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
13.04.2013, 10:09
Длинно писать, что есть ручной инлайн, можно, а инлайнить большие функции средствами языка нельзя? Что за бред?

Добавлено через 7 минут
Нельзя злоупотреблять инлайном, а не инлайнить длинный функции. Функция может быть в 100 строк и инлайниться в 1000 разных мест в программе, что плохо, другая функция может занимать 5000 строк и инлайниться дважды, что примерно в десятеро лучше. Примерно потому, что важны не строки исходного текста, а байты исполняемого кода, а одно с другим связано не так однозначно, как это интуитивно представляется. Но если большая функция инлайнится один раз в цикл в 1000 шагов, то имеет только один экземпляр, это просто цикл с длинным телом, не более. Наоборот, цикл в инлайн-функции - это просто цикл. Именно ручное избыточное упоминание длинных инлайн-функций плохо. Не само их наличие и не использование в цикле, а именно многократное ручное упоминание.
0
9 / 9 / 9
Регистрация: 19.09.2011
Сообщений: 272
13.04.2013, 12:59  [ТС]
Цитата Сообщение от taras atavin Посмотреть сообщение
Длинно писать, что есть ручной инлайн, можно, а инлайнить большие функции средствами языка нельзя? Что за бред?

Добавлено через 7 минут
Нельзя злоупотреблять инлайном, а не инлайнить длинный функции. Функция может быть в 100 строк и инлайниться в 1000 разных мест в программе, что плохо, другая функция может занимать 5000 строк и инлайниться дважды, что примерно в десятеро лучше. Примерно потому, что важны не строки исходного текста, а байты исполняемого кода, а одно с другим связано не так однозначно, как это интуитивно представляется. Но если большая функция инлайнится один раз в цикл в 1000 шагов, то имеет только один экземпляр, это просто цикл с длинным телом, не более. Наоборот, цикл в инлайн-функции - это просто цикл. Именно ручное избыточное упоминание длинных инлайн-функций плохо. Не само их наличие и не использование в цикле, а именно многократное ручное упоминание.
Спасибо за интересные пояснения) под "ручным упоминанием" вы имеете ввиду?
C++
1
inline void func()
Насколько меня учили, нормальные современные компиляторы с включённой оптимизацией всегда стараются инлайнить функцию в код.
а у вас нет мыслей относительно того, почему наличие директив OpenMP в функции снижает производительность более чем в 2 раза?
0
 Аватар для taras atavin
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
13.04.2013, 13:22
Цитата Сообщение от IcyWind Посмотреть сообщение
Спасибо за интересные пояснения) под "ручным упоминанием" вы имеете ввиду?
inline void func()
то, что для обычной функции было бы её вызовом, но
C++
1
2
3
4
5
6
7
8
9
10
11
12
inlune void f()
{
};
....
for (i=1; i<1000000000; ++i)
{
 f();//это считаем за одно, а не миллиард, так как оно только однажды прописано вручную
};
...
f(); // это тоже считаем
...
f(); // и это считаем отдельно
. Итого в этом тексте функция упомянута трижды, а выполнится 1000000002 раза. Считаем, сколько раз она упомянута, а не сколько раз выполнится.

Добавлено через 4 минуты
Цитата Сообщение от IcyWind Посмотреть сообщение
Насколько меня учили, нормальные современные компиляторы с включённой оптимизацией всегда стараются инлайнить функцию в код.
Не всегда. Чем больше инлайнов, тем больше программа, а большая программа при прочих равных работает медленнее, так как:
1. Меньшая её доля помещается в кеш.
2. Она нуждается в большем количестве подгрузок страниц с диска.
Поэтому и стараются инлайнить в первую очередь короткие функции, так как это мало влияет на общий размер. Но при этом учитывается и частота вызовов, и их количество, так как на количество (в примере на 3) идёт умножение размера функции.

Добавлено через 5 минут
Если функция вызывается ровно в одном месте, она должна быть заинлайнена не зависимо длины самой функции, числа шагов цикла, в который она вложена и шагов цикла внутри самой функции, так как размер от этого не вырастет, а пара вызов/возврат сократится. Но если даже маленькая функция в пару строк вызывается в миллиарде различных строк, инлайнить её во все эти строки нельзя, тогда надо смотреть, куда именно заинлайнить выгодней, возможно вообще отказаться от инлайна.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
13.04.2013, 13:22
Помогаю со студенческими работами здесь

Memo замедляет работу
Здравствуйте. var i: Integer; begin for i:=0 to 100000 do Memo1.Lines.Add(IntToStr(i)); end; При цикле, когда вывод...

Почему PFD_DOUBLEBUFFER замедляет работу?
Доброго времени суток. Последние несколько часов открываю для себя плюшки OpenGL, всё конечено круто, но в ходе тестирования обнаружилось,...

Замедляет ли работу приведенная конструкция
Вопрос такой к примеру замедляет ли работу выборки такие вот конструкции к примеру ,или точно я буду выбирать запрос в запросе это...

Вирус замедляет и останавливает работу браузера
в общем недавно началась проблема,а если точнее 2-3 дня назад,что при работе браузера опера начинают резко останавливаться станадартные...

Насколько блок try-catch замедляет работу программы?
У меня возник следующий вопрос, насколько блок try-catch замедляет работу программы, стоит ли избегать при возможности данной процедуры ,...


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

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru