Опубликован: 11.10.2012 | Уровень: специалист | Доступ: платный
Лекция 1:

Компиляторы Intel. Возможности автоматической оптимизации

Лекция 1: 1234 || Лекция 2 >

Оптимизация под архитектуру

/Qax (Windows), -ax (Linux)

  • Оптимизация под архитектуру Intel (использование векторных расширений инструкций)
  • QxHost
  • QxAVX
  • QxSSE2, QxSSE3, QxSSE3_ATOM, QxSSE4.1, QxSSE4.2, QxSSSE3

Пример 2

Primes.cpp

#include "time.h"
#include <iostream>
    #include "stdlib.h"
    #include "conio.h"
    #include "math.h"
    
    using namespace std;
    const int NUM_OF_TESTS = 2000000;
    const int RANGE = 1000;
    bool isComposite(const int y);
    
    int main()
    {
    time_t t1, t2;
    int counter(0);
    t1 = clock();
    for	(int i = 0; i < NUM_OF_TESTS; i++)
    if(isComposite(rand()%RANGE))
    ++counter;
    t2 = clock();
    
    cout << "For " << NUM_OF_TESTS << " pseudo-random values" << endl;
    cout << "within the range 0.." << RANGE << endl;
    cout << ((NUM_OF_TESTS-counter)*100.0)/NUM_OF_TESTS << "% were prime numbers." << endl;
    cout << "\nInitial clock ticks value is " << t1 << endl;
    cout << "Final clock ticks value is " << t2 << endl;
    cout << "Difference in clock ticks is " << difftime(t2,t1) << endl;
    cout << "Clock ticks per second value is " << CLOCKS_PER_SEC << endl;
    cout << "\nActual time of calculations is " << ((t2-t1)/CLOCKS_PER_SEC) << " sec" << endl;
    return 0;
    }
    
    bool isComposite(const int y)
    {
    bool result = false;
    
    for (int i = 2; i <= ceil(y/2.0); i++)
        {	
        if (y%i == 0) result = true;
        }
        return result;
        }
        
        

Подготовим тест:

  • icl /FePOd /Od Primes.cpp
  • icl /FePx /QaxSSSE3 Primes.cpp

Сравнить результаты

Intel Core 2 Duo T3700 2.00 ГГц, 2 Гб ОЗУ

Среднее значение времени выполнения:

  • POd . . . . . 29.8 с.
  • Px . . . . . . 4.5 с.

Вопрос. Объясните результаты теста.

Автоматическое распараллеливание

/Qparallel (Windows), -parallel (Linux)

  • Автоматическое распараллеливание.
  • Определяются те части кода, которые можно распараллелить.
  • Выполняется анализ зависимостей.
  • Разделение данных для параллельной обработки.
  • Работа с циклами.

Пример 3

FermatsCubes.cpp

#include "time.h"
#include <iostream>
    #include "stdlib.h"
    #include "conio.h"
    #include "math.h"
    using namespace std;
    const int RANGE = 2000;
    long sumOfCubes(const int x, const int y);
    int main()
    {
    time_t t1, t2;
    bool isDisproven = false;
    cout << "Checking for mispredictions of Fermat's Great Theorem" << endl;
    cout << "for cubes in range 3.." << RANGE << endl;
    t1 = clock();
    for (int i = 3; i < RANGE; i++)
    {
    for(int k = 1; k < i; k++)
    {
    for(int j = 1; j < i; j++)
    {
    if (long(i*i*i) == sumOfCubes(k,j)) 
    {
    cout << k << " " << j << " " << i << endl;
    isDisproven = true;
    }
    }
    }
    }
    t2 = clock();
    cout << "\nAre theorem's predictions correct? +" << !(isDisproven) << endl;
    cout << "\nInitial clock ticks value is " << t1 << endl;
    cout << "Final clock ticks value is " << t2 << endl;
    cout << "Difference in clock ticks is " << difftime(t2,t1) << endl;
    cout << "Clock ticks per second value is " << CLOCKS_PER_SEC << endl;
    cout << "\nActual time of calculations is " << ((t2-t1)/CLOCKS_PER_SEC) << " sec" << endl;
    return 0;
    }
    long sumOfCubes(const int x, const int y)
    {
    return (x*x*x + y*y*y);
    }    
        

Подготовим тест:

  • icl /FeFCOd /Od FermatsCubes.cpp
  • icl /FeFCPar /Qparallel FermatsCubes.cpp

Среднее значение времени выполнения:

  • FCOd . . . . . 25.95 с.
  • FCPar . . . . . 3.78 с.

Вопрос. Объясните результаты теста.

Оптимизация с профилированием

/Qprof-gen (Windows), -prof-gen (Linux)

/Qprof-use (Windows), -prof-use (Linux)

  • Инструментовка.
  • Сбор информации.
  • Компиляция с учетом проанализированных данных.

Пример 4

Branches.cpp

#include "time.h"
#include <iostream>
    #include "stdlib.h"
    #include "conio.h"
    #include "math.h"
    using namespace std;
    bool slow_func(void);
    bool quick_func(void);
    
    int main()
    {
    time_t t1, t2;
    t1 = clock();
    if(slow_func() && quick_func()) cout << "You can't see this...";
    t2 = clock();
    cout << "\nInitial clock ticks value is " << t1 << endl;
    cout << "Final clock ticks value is " << t2 << endl;
    cout << "Difference in clock ticks is " << difftime(t2,t1) << endl;
    cout << "Clock ticks per second value is " << CLOCKS_PER_SEC << endl;
    cout << "\nActual time of calculations is " << ((t2-t1)/CLOCKS_PER_SEC) << " sec" << endl;
    return 0;
    }
    
    bool slow_func(void)
    {	
    double a(0);
    for(int i = 0; i < 50000000; i++) 
    a = pow((sin(a/2.0)+cos(a/2.0))*(sin(i/2.0)+cos(i/2.0)), 2);
    for(int i = 0; i < 100; i++)
    a += i;
    return !a;
    }
    
    bool quick_func(void)
    {	
    return false;
    }
    
        

Подготовим тест:

  • icl /FeBOd /Od Branches.cpp
  • icl /FeBPrg /Qprof-gen Branches.cpp
  • BPrg.exe
  • icl /FeBProf /Qprof-use Branches.cpp

Сравним результаты.

Среднее значение времени выполнения:

  • BOd . . . . . 13.171 с.
  • BProf . . . . . 0.0 с.

Вопрос. Объясните результаты теста.

Лекция 1: 1234 || Лекция 2 >
Евгений Звягин
Евгений Звягин
Россия, Липецк, Липецкий Государственный Технический Университет, 2014
Артур Гибадуллин
Артур Гибадуллин
Россия, Нижневартовск, ФГБОУ ВО НВГУ, Преподаватель