2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему На страницу Пред.  1, 2, 3
 
 Re: Зловещие циклы
Сообщение02.05.2020, 18:41 
Экс-модератор
Аватара пользователя


23/12/05
12046
По умолчанию - это без оптимизации. С точки зрения оценки производительности - бесполезные сведения.

 Профиль  
                  
 
 Re: Зловещие циклы
Сообщение02.05.2020, 20:24 
Заслуженный участник


20/08/14
11071
Россия, Москва
Код внутреннего цикла (с метки L4) не то чтобы совсем ужасный, но и до хорошего ему ещё пахать и пахать. Из очевидного:
- все переменные хранить в регистрах, включая и [rbp-8];
- отказаться от cdqe заменив тип переменных;
- отказаться от lea rdx,[0+rax*8] изменив величину инкремента;
- векторизовать операции с xmm хотя бы вдвое за счёт ширины регистров (а лучше в 8 раз, развернув цикл вчетверо для учёта латентности операций);
- использовать имеющийся AVX и ещё вдвое увеличить параллелизм за счёт ширины регистров.
В идеале код внутреннего цикла (с метки L4) без векторизации и разворота цикла должен уложиться в 6-8 команд, 3-4 из которых вычислительные (movsd, movsd (может и отсутствовать), mulsd, addsd), одна условного перехода и остальные скалярные изменения указателей и счётчиков. Причём на скорость выполнения метод обхода массивов (по столбцам или по строкам) влиять не должен (пока массивы целиком помещаются в L1d).
Скорость выполнения для массивов 2048 элементов составила 1.7мкс для скалярного цикла без разворота, 0.78мкс с разворотом цикла вчетверо, 0.36мкс с разворотом цикла вчетверо и векторизацией вдвое, 0.24мкс с разворотом цикла вчетверо и векторизацией вчетверо (AVX), 0.5мкс с векторизацией вчетверо (AVX). Это при одном плавающем блоке вычислений, у процессора ТС их два и скорость будет ещё выше.

 Профиль  
                  
 
 Re: Зловещие циклы
Сообщение02.05.2020, 23:42 


07/10/15

2400
Следуя полученным советам, установил полировщик. Перепробовал много всего, пока остановился на Visual Studio 2010 Ultimate. Только его мне удалось приспособить под все свои задачи. Единственный минус - версия старовата. Как нибудь, планирую опробовать MSVC 2012.

В целом, новые возможности радуют. Удобнее, быстрее, да и наверное точнее

 Профиль  
                  
 
 Re: Зловещие циклы
Сообщение03.05.2020, 08:40 


12/07/15
2907
г. Чехов
Выложу сюда код, который я подсовываю в https://godbolt.org для просмотра компилированного кода.

Вариант 1 (медленный):
код: [ скачать ] [ спрятать ]
Используется синтаксис C++
#include <cstdlib>
double func(){
    int Lstr=1000;
    int nVar=1000;    
    double val;
    double *X = static_cast<double *> (malloc(nVar * sizeof(double)));
    double *b = static_cast<double *> (malloc(nVar * sizeof(double)));
    double *pos_x;

    for (int j=0; j<Lstr; j++) {
        val=0;
        pos_x=X+j*nVar;  
        for (int ii=0; ii<nVar; ii++) {
            val+=b[ii]**pos_x;
            pos_x++;
        }
    }
    return val;
}


Вариант 2 (быстрый):
код: [ скачать ] [ спрятать ]
Используется синтаксис C++
#include <cstdlib>
double func(){
    int Lstr=1000;
    int nVar=1000;    
    double val;
    double *X = static_cast<double *> (malloc(nVar * sizeof(double)));
    double *b = static_cast<double *> (malloc(nVar * sizeof(double)));
    double *pos_x;

    for (int j=0; j<Lstr; j++) {
        val=0;
        pos_x=X+j;  
        for (int ii=0; ii<nVar; ii++) {
            val+=b[ii]**pos_x;
            pos_x+=Lstr;
        }
    }
    return val;
}


Результат компиляции варианта 1 x86-64 gcc 9.3 с ключом -O2:
код: [ скачать ] [ спрятать ]
Используется синтаксис ASM
func():
        push    rbx
        mov     edi, 8000
        call    malloc
        mov     edi, 8000
        mov     rbx, rax
        call    malloc
        mov     rdx, rbx
        lea     rsi, [rbx+8000000]
        pxor    xmm2, xmm2
        mov     rcx, rax
.L3:
        xor     eax, eax
        movapd  xmm1, xmm2
.L2:
        movsd   xmm0, QWORD PTR [rcx+rax]
        mulsd   xmm0, QWORD PTR [rdx+rax]
        add     rax, 8
        addsd   xmm1, xmm0
        cmp     rax, 8000
        jne     .L2
        add     rdx, 8000
        cmp     rsi, rdx
        jne     .L3
        movapd  xmm0, xmm1
        pop     rbx
        ret


Результат компиляции варианта 2 x86-64 gcc 9.3 с ключом -O2:
код: [ скачать ] [ спрятать ]
Используется синтаксис ASM
func():
        push    rbx
        mov     edi, 8000
        call    malloc
        mov     edi, 8000
        mov     rbx, rax
        call    malloc
        lea     rcx, [rbx+8000000]
        lea     rsi, [rbx+8008000]
        pxor    xmm2, xmm2
        mov     rdi, rax
.L3:
        lea     rax, [rcx-8000000]
        mov     rdx, rdi
        movapd  xmm1, xmm2
.L2:
        movsd   xmm0, QWORD PTR [rdx]
        mulsd   xmm0, QWORD PTR [rax]
        add     rax, 8000
        add     rdx, 8
        addsd   xmm1, xmm0
        cmp     rax, rcx
        jne     .L2
        lea     rcx, [rax+8]
        cmp     rcx, rsi
        jne     .L3
        movapd  xmm0, xmm1
        pop     rbx
        ret

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 34 ]  На страницу Пред.  1, 2, 3

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group