<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE article
PUBLIC "-//NLM//DTD JATS (Z39.96) Journal Publishing DTD v1.4 20190208//EN"
       "JATS-journalpublishing1.dtd">
<article xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" article-type="research-article" dtd-version="1.4" xml:lang="en">
 <front>
  <journal-meta>
   <journal-id journal-id-type="publisher-id">Automation and modeling in design and management</journal-id>
   <journal-title-group>
    <journal-title xml:lang="en">Automation and modeling in design and management</journal-title>
    <trans-title-group xml:lang="ru">
     <trans-title>Автоматизация и моделирование в проектировании и управлении</trans-title>
    </trans-title-group>
   </journal-title-group>
   <issn publication-format="print">2658-3488</issn>
   <issn publication-format="online">2658-6436</issn>
  </journal-meta>
  <article-meta>
   <article-id pub-id-type="publisher-id">24632</article-id>
   <article-id pub-id-type="doi">10.30987/article_5c387d60657774.94658729</article-id>
   <article-categories>
    <subj-group subj-group-type="toc-heading" xml:lang="ru">
     <subject>Математическое моделирование, численные методы и комплексы программ</subject>
    </subj-group>
    <subj-group subj-group-type="toc-heading" xml:lang="en">
     <subject>Mathematical modeling, numerical methods and program complexes</subject>
    </subj-group>
    <subj-group>
     <subject>Математическое моделирование, численные методы и комплексы программ</subject>
    </subj-group>
   </article-categories>
   <title-group>
    <article-title xml:lang="en">STUDY OF FACTORS INFLUENCING THE SPEED OF CALLING PROCEDURES, LANGUAGE C++</article-title>
    <trans-title-group xml:lang="ru">
     <trans-title>ИССЛЕДОВАНИЕ ФАКТОРОВ, ВЛИЯЮЩИХ НА СКОРОСТЬ ВЫЗОВА ПРОЦЕДУР ЯЗЫКА С++</trans-title>
    </trans-title-group>
   </title-group>
   <contrib-group content-type="authors">
    <contrib contrib-type="author">
     <name-alternatives>
      <name xml:lang="ru">
       <surname>Асланов</surname>
       <given-names>Геворк Артурович</given-names>
      </name>
      <name xml:lang="en">
       <surname>Aslanov</surname>
       <given-names>Gevorg Arturovich</given-names>
      </name>
     </name-alternatives>
     <email>gevork5@mail.ru</email>
     <xref ref-type="aff" rid="aff-1"/>
    </contrib>
    <contrib contrib-type="author">
     <name-alternatives>
      <name xml:lang="ru">
       <surname>Сугарова</surname>
       <given-names>Лаура Феликсовна</given-names>
      </name>
      <name xml:lang="en">
       <surname>Sugarova</surname>
       <given-names>Laura Feliksovna</given-names>
      </name>
     </name-alternatives>
     <xref ref-type="aff" rid="aff-2"/>
    </contrib>
   </contrib-group>
   <aff-alternatives id="aff-1">
    <aff>
     <institution xml:lang="ru">Северо-Кавказский горно-металлургический институт (государственный технологический университет)</institution>
    </aff>
    <aff>
     <institution xml:lang="en">North Caucasian Institute of Mining and Metallurgy (State Technological University)</institution>
    </aff>
   </aff-alternatives>
   <aff-alternatives id="aff-2">
    <aff>
     <institution xml:lang="ru">ГБОУ &quot;Гимназия &quot;Диалог&quot;</institution>
     <city>Владикавказ</city>
     <country>Россия</country>
    </aff>
    <aff>
     <institution xml:lang="en">GBOU &quot;High School&quot;Dialogue&quot;</institution>
     <city>Владикавказ</city>
     <country>Russian Federation</country>
    </aff>
   </aff-alternatives>
   <volume>2018</volume>
   <issue>2</issue>
   <fpage>4</fpage>
   <lpage>8</lpage>
   <self-uri xlink:href="https://zh-szf.ru/en/nauka/article/24632/view">https://zh-szf.ru/en/nauka/article/24632/view</self-uri>
   <abstract xml:lang="ru">
    <p>Данная статья является продолжением одной работы по определению оптимальной стратегии макрозамен при оптимизации программных кодов С++. Макрозамены для подпрограмм – это разворачивание кода функции во всех местах ее вызова. В статье описываются результаты экспериментов по определению факторов влияющих на скорость вызова подпрограмм. Изначально считалось, что на время вызова функций влияют время выделения стека функции и время на передачу управления подпрограмме. В связи с результатами эксперимента было установлено, что время на передачу управления является незначительным по сравнению с временем выделения стековой памяти. Время выделения стековой памяти подпрограммы напрямую зависит от объема кода и количества стековых объектов, используемы в данной подпрограмме. Для оптимизации скорости программы можно использовать 2 варианта макрозамен. Первый – использование специального модификатора языка С++ (inline/__forceinline), а второй – прямая подстановка кода в место вызова. В отношении эффективности между этими методами практически нет никакой разницы, за исключением того, что в стратегии подстановки кода программист сам должен контролировать возникающие ошибки. Поэтому для экспериментов был выбран метод использование специального модификатора. Был выбран модификатор __forceinline, так как при обычном inline компилятор может игнорировать рекомендации программиста и не выполнять макрозамену, если по алгоритмам оптимизации самого компилятора она не нужна. А __forceinline гарантированно выполнит макрозамену. В связи с полученными результатами можно сделать вывод, что макрозамены значительно увеличивают скорость работы программы, но могут приводить к увеличению размера исполняемого файла.</p>
   </abstract>
   <trans-abstract xml:lang="en">
    <p>This article is a continuation of one work to determine the optimal strategy of macro-replacement in the optimization program codes of C++. Macro-replacement for routines is to deploy the function code in all the places her call. The article describes the results of experiments to determine the factors affecting the speed of subroutines. Initially, it was believed that function call times are affected by the time the function stack is allocated and the time to transfer control to the function. In connection with the results of the experiment, it was established that the time for transfer of control is insignificant compared to the time of allocation of memory. The time that the stack memory of a function allocated depends on the amount of code and the number of stack objects used by the function. To optimize the speed of the program, you can use two variants of macro-replacement. The first is the use of a special C++ language modifier (in-line/__forceinline), and the second is a direct substitution of the code in the place of the call. There is almost no difference in the effectiveness of these methods, except that the programmer has to control the errors in the code substitution strategy. Therefore, the method of using a special modifier was chosen for experiments. Was selected modifier __forceinline, because in a typical inline, the compiler may ignore the programmer recommendations and not done macro-replacement, if the optimization algorithms of the compiler don't need it. And __forceinline is guaranteed to apply macro-replacement. In connection with the results obtained, it can be concluded that macro-replacement significantly increases the speed of the program but can lead to an increase in the size of the executable file.</p>
   </trans-abstract>
   <kwd-group xml:lang="ru">
    <kwd>программный код</kwd>
    <kwd>оптимизация</kwd>
    <kwd>модель</kwd>
    <kwd>качество</kwd>
    <kwd>производительность</kwd>
   </kwd-group>
   <kwd-group xml:lang="en">
    <kwd>program code</kwd>
    <kwd>optimization</kwd>
    <kwd>model</kwd>
    <kwd>quality</kwd>
    <kwd>output</kwd>
   </kwd-group>
  </article-meta>
 </front>
 <body>
  <p>ВведениеЦелью проведенного исследования является: определение факторов, влияющих на скорость вызова функции в языке С++.Значение прироста в производительности в результате макрозамен включает два слагаемых: 1) время на передачу управления в функцию и возврат из неё; 2) время на выделение стековой памяти функции, необходимой для размещения всех локальных переменных и массивов, - и может быть представлено в виде выражения (1):                      (1)     – время на передачу управления в функцию и возврат из нее без учета времени, необходимого на выделение локального стека функции. Эта величина является постоянной и соответствует времени выполнения машинной инструкции CALL(передающей управление процедуре на языке Ассемблера).  – время, затрачиваемой на выделение локальной (стековой) памяти, предназначенной для размещения переменных, объявленных внутри блока функции. Это время зависит от суммарного размера локальных данных, ниже данное утверждение будет подтверждено экспериментально.Чтобы оценить порядок величин  ,   и оценить их значимость в выражении (1) были проведены ряд экспериментов. Экспериментальные замеры проводились с помощью тестового кода, написанного на языке C++ в среде Visual Studio. Для получения максимально объективных оценок в настройках проекта параметру «Optimization» было присвоено значение «Disabled (/Od)», что предотвращает влияние встроенных в компилятор Microsoft методов оптимизации. Кроме того, параметр «Inline function expansion» был установлен в «Only __inline (/Ob1)» - данный флаг запрещает компилятору игнорировать инструкцию inline при построении исполняемого кода (рис.1). Замеры проводились в режиме «Release» для исключения диагностического кода. Рис. 1. Настройки тестового проекта1. Процесс тестированияДля оценки величины времени вызова и возврата из функции    был проведен тест, в котором замерялось время выполнения кода, выполняющего в цикле функцию с пустым телом и без параметров (чтобы исключить влияние операторов выделения стека). Количество итераций цикла последовательно изменялось от 1000000 до 20000000 с шагом 1000000. Исходный код теста имеет вид:    CString cstr=&quot;&quot;;    for (int N=1000000; N&lt;=20000000; N+=1000000){        DWORD dwStart = GetTickCount();        for (int i=0; i&lt;N; i++){            f();        }        DWORD dwTime = GetTickCount() - dwStart;        CString cs; cs.Format(&quot;%u\n&quot;,dwTime);        cstr += cs;    }    AfxMessageBox(cstr); Были проведены два замера: в первом функция была объявлена обычным образом:void f(){}Во втором случае с использованием инструкции _forceinline:__forceinline void f(){}Результаты замеров показали, что отличия во времени работы лежали в пределах статистической погрешности. Максимальное время выполнения (для 20000000 итераций) составило около 47 микросекунд.Так как существовала возможность того, что компилятор игнорирует флаг запрета встроенной оптимизации и все-таки исключает функции с пустым телом из объектного кода, то были проведены 2 дополнительных теста: в первом вместо функции f() в цикле вызывалось выражение log(10.5):CString cstr=&quot;&quot;;    for (int N=1000000; N&lt;=20000000; N+=1000000){        DWORD dwStart = GetTickCount();        for (int i=0; i&lt;N; i++){            log(10.5);        }        DWORD dwTime = GetTickCount() - dwStart;        CString cs; cs.Format(&quot;%u\n&quot;,dwTime);        cstr += cs;    }    AfxMessageBox(cstr); А во втором тесте выражение log(10.5); было помещено в тело функции f():void f(){    log(10.5);}Сравнение результатов этих двух тестов также показало очень незначительные расхождение. Это говорит о том, что затраты на вызов функции и возврат из неё незначительны. Выражение (1) примет следующий вид:                     (2)Для оценки зависимости времени выделения стековой памяти от размера локальных данных был проведен следующий эксперимент: число итераций было зафиксировано значением 20000000, Далее были проведены 10 замеров для каждого из которых менялся размер массива «y», объявленного в теле функции f()  (Листинг 1) от 100000 до 1000000 байт включительно:void f(){    char y[1000000];    y[0] = &amp;#39;a&amp;#39;;}2. Результаты экспериментовАналогичный эксперимент был проведен для варианта функции f() с использованием модификатора __forceinline. Результаты обоих экспериментов приведены в таблице 1.Полученные результаты говорят о высокой эффективности использования модификатора __forceinline: очевидно, что объявление данных компилятор поместил перед циклом. На графике, изображенном на рисунке 2 хорошо виден линейный характер зависимости времени выделения локального стека функции от его размера: поверх кривой экспериментальных данных, взятых из первой и второй колонок таблицы 1, проведена прямая (пунктиром), коэффициенты, которой получены аппроксимацией данных методом МНК.Таблица 1 - Результаты замеров времени выделения локальной памятиРазмер данных    время работы обычной функции    время работы __forceinline функции100000    579    47200000    1312    47300000    2187    47400000    3468    47500000    4343    47600000    5187    47700000    6079    47800000    6922    47900000    7781    471000000    8641    47 Рис. 2. Кривая экспериментальных данных и прямая, описывающая линейную зависимость времени выделения стековой памяти от её размера.На графике, изображенном на рисунке 2 ось абсцисс, соответствует размеру стека (в байтах), а ось ординат – времени выделения стека (в миллисекундах).Проведенные эксперименты показали, что в выражение (1) можно упростить, убрав из него представив выигрыш от макрозамены  , ввиду его фактической несущественности. Кроме того, подтвержденный экспериментально линейный характер зависимости времени выделения стека от его размера позволяет с высокой степенью точности использовать для прогнозирования времени выделения стека коэффициенты пропорциональности либо более наглядный показатель скорости выделения стека, с учетом этого выражение (1) можно преобразовать в следующее (2):                         (2)  – суммарный размер локальных переменных (стека функции);     – скорость выделения стека.ВыводыВ методе макрозамен, как и во всех задачах, относящихся к категории моделей «экстремального программирования», улучшение качества программы достигается за счет использования дополнительных вычислительных ресурсов. Макрозамены приводят к увеличению размера кода программы пропорционально количеству вызовов функций, для которых такая замена будет осуществляться. Естественно, в сложных системах с большим числом функций, неограниченное использование макрозамен невозможно – прежде всего из-за того, что оперативная память, используемая для размещения исполняемого кода, является ресурсом достаточно дорогим. Таким образом имеет место оптимизационная проблема выбора стратегии макрозамен, улучшающей производительность кода, в условиях ограниченного объема ресурсов оперативной памяти, необходимого для достижения данной цели. </p>
 </body>
 <back>
  <ref-list>
   <ref id="B1">
    <label>1.</label>
    <citation-alternatives>
     <mixed-citation xml:lang="ru">Томаев М.Х., Асланов Г.А., Ванюшенкова Н.В. Использование оптимизационных моделей экстремального программирования в проектировании ПО // IT-Технологии: теория и практика, Материалы семинара, 2017.</mixed-citation>
     <mixed-citation xml:lang="en">Tomaev M.KH., Aslanov G.A., Vanyushenkova N.V. (2017). Use of optimization models of extreme programming in software design. IT-Technologies: theory and practice, Seminar materials. [in Russian language]</mixed-citation>
    </citation-alternatives>
   </ref>
   <ref id="B2">
    <label>2.</label>
    <citation-alternatives>
     <mixed-citation xml:lang="ru">Соколова Е.А., Определение параметров быстродействия алгоритма компрессии статичных изображений // Междунар. науч. конф. молодых ученых, студентов и аспирантов «Перспектива-2008»: сб. матер. Нальчик: Каб.-Балк. ун-т, 2008. С.143-147.</mixed-citation>
     <mixed-citation xml:lang="en">Sokolova E.A. (2008). Determination of the parameters of the speed of the compression algorithm for static images. International scientific conference young scientists, students and post-graduate students «Perspective-2008»: Cal. mater. Nalchik: Cab-Balk. University, pp.143-147. [in Russian language]</mixed-citation>
    </citation-alternatives>
   </ref>
   <ref id="B3">
    <label>3.</label>
    <citation-alternatives>
     <mixed-citation xml:lang="ru">Соколова Е.А. Математическая модель компрессии статичных изображений вариабельными фрагментами с учетом погрешностей // деп. в ВИНИТИ 19.07.07. № 748-В2007, указатель № 9, 12 с.</mixed-citation>
     <mixed-citation xml:lang="en">Sokolova E.A. (2007) Mathematical model of compression of static images with variable fragments taking into account errors. Dep. in VINITI No. 748-B2007, the index No. 9. [in Russian language]</mixed-citation>
    </citation-alternatives>
   </ref>
   <ref id="B4">
    <label>4.</label>
    <citation-alternatives>
     <mixed-citation xml:lang="ru">Соколова Е.А. К проблеме повышения эффективности компрессии изображений // Безопасность информационных технологий, Министерство образования и науки РФ, МИФИ, ВНИИПТИ. 2008. № 2. С.57-60.</mixed-citation>
     <mixed-citation xml:lang="en">Sokolova E.A. (2008). To the problem of increasing the efficiency of image compression. Information Technology Security, Ministry of Education and Science of the Russian Federation, MEPhI, VNIIPTI, (2), pp. 57-60. [in Russian language]</mixed-citation>
    </citation-alternatives>
   </ref>
   <ref id="B5">
    <label>5.</label>
    <citation-alternatives>
     <mixed-citation xml:lang="ru">Соколова Е.А. Разработка метода сохранения пикселей в массив с дифференциацией на цветовые компоненты // Международный научно-исследовательский журнал. 2017. № 7 (61). С. 7.</mixed-citation>
     <mixed-citation xml:lang="en">Sokolova E.A. (2017). Development of a method for storing pixels in an array with differentiation into color components. International Scientific and Research Journal, 61(7). [in Russian language]</mixed-citation>
    </citation-alternatives>
   </ref>
   <ref id="B6">
    <label>6.</label>
    <citation-alternatives>
     <mixed-citation xml:lang="ru">Соколова Е.А. Метод компрессии цифровых трехмерных изображений с помощью анализа таблицы текстурных координат // Международный научно-исследовательский журнал. 2017. № 7 (61). С. 9.</mixed-citation>
     <mixed-citation xml:lang="en">Sokolova E.A. (2017). The method of compression of digital three-dimensional images using the analysis of the table of texture coordinates. International Scientific and Research Journal, 61(7). [in Russian language]</mixed-citation>
    </citation-alternatives>
   </ref>
  </ref-list>
 </back>
</article>
