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

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

Восстановить пароль Регистрация
 
IcyWind
8 / 8 / 2
Регистрация: 19.09.2011
Сообщений: 268
11.04.2013, 16:12     Инлайн-функция замедляет работу #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
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 раза быстрее работает
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
11.04.2013, 16:12     Инлайн-функция замедляет работу
Посмотрите здесь:

C++ завершает работу ...
Попроавить работу C++
Как отключить инлайн в MSVS2008? C++
std::map в инлайн-асме C++
Переделать работу с текстовыми файлами под работу с двоичными файлами C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
11.04.2013, 16:21     Инлайн-функция замедляет работу #2
IcyWind, Инлайтить большие функции - это как-то грустно, не находите? К слову, совсем не факт, что функция будет заинлайнена
IcyWind
8 / 8 / 2
Регистрация: 19.09.2011
Сообщений: 268
11.04.2013, 17:00  [ТС]     Инлайн-функция замедляет работу #3
Хорошо. Допустим, что она не инлайнится в функцию мейн. Тогда единственным накладным расходом будет именно вызов этой функции. Тогда всё-равно непонятно! Ведь, когда я замеряю производительность внутри самой функции - то получаю ту же картину - падение производительности примерно в 2 раза
Игорь с++
 Аватар для Игорь с++
429 / 452 / 15
Регистрация: 26.01.2011
Сообщений: 2,029
11.04.2013, 17:29     Инлайн-функция замедляет работу #4
вам уже сказали , что инлайнить большие функции нельзя , почитайте про это , да и ещё компилятор видать совсем идиот если даёт это делать.Удачи
stima
430 / 285 / 16
Регистрация: 22.03.2011
Сообщений: 929
Завершенные тесты: 1
11.04.2013, 17:39     Инлайн-функция замедляет работу #5
Инлайнить большие функции можно, если нужно. Но есть одно ограничение inline это всего лишь пожелание к компилятору, а не строгое указание. Поэтому он оставляет за собой право встроить или нет (в данном случае нет ибо есть цикл). В вашем случае при инлайне не срабатывает #pragma omp parallel. Если вы знаете с чем работаете читайте маны, если нет, то мой вам совет не трогайте код.
IcyWind
8 / 8 / 2
Регистрация: 19.09.2011
Сообщений: 268
11.04.2013, 19:45  [ТС]     Инлайн-функция замедляет работу #6
Цитата Сообщение от stima Посмотреть сообщение
Инлайнить большие функции можно, если нужно. Но есть одно ограничение inline это всего лишь пожелание к компилятору, а не строгое указание. Поэтому он оставляет за собой право встроить или нет (в данном случае нет ибо есть цикл). В вашем случае при инлайне не срабатывает #pragma omp parallel. Если вы знаете с чем работаете читайте маны, если нет, то мой вам совет не трогайте код.
c OMP я не знаком - знаю только базовые функции и директивы. Читал несколько поверхностных статей + на лекциях тоже в глубины не вдавались - слишком мало часов выделено. Код не получится "не трогать" - стоит учебная задача - вот и пытаюсь разобраться. Про инлайн я знал, что это всего-лишь пожелание.Не смотря на то, что всё обёрнуто в конструкции OMP все тесты пока проводил только на одном потоке. Меня просто поразило то, как резко падала производительность после перевода кода в функцию.
И, кстати, если в функции полностью закомментировать директивы openmp, то производительность нормализуется.
Не подскажете, как обернуть функцию в параллельную секцию? или статьи на эту тему?
и, если есть идеи как ускорить алгоритм, не используя ассемблерные вставки или другие низкоуровневые конструкции, буду очень благодарен) то, что выложил - пока предел моих знаний)
Игорь с++
 Аватар для Игорь с++
429 / 452 / 15
Регистрация: 26.01.2011
Сообщений: 2,029
11.04.2013, 22:09     Инлайн-функция замедляет работу #7
Цитата Сообщение от stima Посмотреть сообщение
Инлайнить большие функции можно, если нужно
Покажи мне такого дурака который использует большие инлайн ! И что значит нужно ? Кому нужно ? Приведи реальный хоть один пример когда это обаснованно использовать , и компилятор тебя не пошлёт .

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

2IcyWind Ээээ батюшка да Вы невнимательно копипастите посмотрите на num_tread(), а я та замахнулся на компилятор грешить. Кстате Ваш алгоритм уже оптимизирован оочень сильно в нем учтена оптимизация на уровне инструкций, а это последняя оптимизация распаралеливания.
IcyWind
8 / 8 / 2
Регистрация: 19.09.2011
Сообщений: 268
12.04.2013, 02:53  [ТС]     Инлайн-функция замедляет работу #9
Что-то не могу найти косяк копипаста...вы имеете ввиду это?
Цитата Сообщение от 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);
stima
430 / 285 / 16
Регистрация: 22.03.2011
Сообщений: 929
Завершенные тесты: 1
12.04.2013, 13:21     Инлайн-функция замедляет работу #10
А время вы тоже засекали на 1 потоке? Если да, то возможно повлияла синхронизация. Но чтобы точно быть знать, если интересно и есть время, дизассемблируйте обе версии посмотрите в чем разница.
Avazart
 Аватар для Avazart
6910 / 5150 / 253
Регистрация: 10.12.2010
Сообщений: 22,656
Записей в блоге: 17
12.04.2013, 13:47     Инлайн-функция замедляет работу #11
Цитата Сообщение от IcyWind Посмотреть сообщение
Хорошо. Допустим, что она не инлайнится в функцию мейн. Тогда единственным накладным расходом будет именно вызов этой функции. Тогда всё-равно непонятно! Ведь, когда я замеряю производительность внутри самой функции - то получаю ту же картину - падение производительности примерно в 2 раза
По идее если ф-ция действительно инлайнится то должен быть прирост скорости, а не падение.
А значит дело в другом( ну или это косвенно влияет) ... то есть для чистоты эксперемента уберите распараллеливание.

Вполне возможно что inline мешает работе omp - поэтому проигрыш.
IcyWind
8 / 8 / 2
Регистрация: 19.09.2011
Сообщений: 268
12.04.2013, 15:06  [ТС]     Инлайн-функция замедляет работу #12
Сначала загорелся желанием дизасемблировать...но потом понял, что это надолго...опыта то у меня нет совсем. Поэтому забил. Могу только поделиться впечатлениями. Падение производительности действительно происходит не из-за функции. Но она каким-то образом косвено влияет (в сочетании с openMP). Теперь поясню:
1.)берём код - кидаем в main() - производительность 3.7 Gflops на одном потоке, 6.8 Gflops на двух.
2.)копируем код в инлайн функцию(), передаём туда матрицы через указатели - ну как в коде. Производительность 2 Gflops на одном потоке, 4Gflops на двух.
3.)убираем слово инлайн - аналогично пункту 2
4.)убираем все упоминания об OpenMp в функции - производительность возвращается на уровень 3.7Gflops
stima
430 / 285 / 16
Регистрация: 22.03.2011
Сообщений: 929
Завершенные тесты: 1
12.04.2013, 16:06     Инлайн-функция замедляет работу #13
Попробуйте обьявить double *A, double *B, double *result как volatile и лучше мувните их в глобал скоп. Думаю компилятор оптимизирует их.
IcyWind
8 / 8 / 2
Регистрация: 19.09.2011
Сообщений: 268
13.04.2013, 08:05  [ТС]     Инлайн-функция замедляет работу #14
Цитата Сообщение от 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 секунд
Видимо тогда придётся держать весь код в мейне)
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
13.04.2013, 10:09     Инлайн-функция замедляет работу #15
Длинно писать, что есть ручной инлайн, можно, а инлайнить большие функции средствами языка нельзя? Что за бред?

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

Добавлено через 7 минут
Нельзя злоупотреблять инлайном, а не инлайнить длинный функции. Функция может быть в 100 строк и инлайниться в 1000 разных мест в программе, что плохо, другая функция может занимать 5000 строк и инлайниться дважды, что примерно в десятеро лучше. Примерно потому, что важны не строки исходного текста, а байты исполняемого кода, а одно с другим связано не так однозначно, как это интуитивно представляется. Но если большая функция инлайнится один раз в цикл в 1000 шагов, то имеет только один экземпляр, это просто цикл с длинным телом, не более. Наоборот, цикл в инлайн-функции - это просто цикл. Именно ручное избыточное упоминание длинных инлайн-функций плохо. Не само их наличие и не использование в цикле, а именно многократное ручное упоминание.
Спасибо за интересные пояснения) под "ручным упоминанием" вы имеете ввиду?
C++
1
inline void func()
Насколько меня учили, нормальные современные компиляторы с включённой оптимизацией всегда стараются инлайнить функцию в код.
а у вас нет мыслей относительно того, почему наличие директив OpenMP в функции снижает производительность более чем в 2 раза?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
13.04.2013, 13:22     Инлайн-функция замедляет работу
Еще ссылки по теме:

Реализация шаблонов класса в инлайн файле C++
C++ Реализация шаблонов класса в инлайн файле
C++ Программа останавливает свою работу, когда начинает выполнятся функция. Метод хорд

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

Или воспользуйтесь поиском по форуму:
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
13.04.2013, 13:22     Инлайн-функция замедляет работу #17
Цитата Сообщение от 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 минут
Если функция вызывается ровно в одном месте, она должна быть заинлайнена не зависимо длины самой функции, числа шагов цикла, в который она вложена и шагов цикла внутри самой функции, так как размер от этого не вырастет, а пара вызов/возврат сократится. Но если даже маленькая функция в пару строк вызывается в миллиарде различных строк, инлайнить её во все эти строки нельзя, тогда надо смотреть, куда именно заинлайнить выгодней, возможно вообще отказаться от инлайна.
Yandex
Объявления
13.04.2013, 13:22     Инлайн-функция замедляет работу
Ответ Создать тему
Опции темы

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