2014 dxdy logo

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

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




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


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

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


20/08/14
11966
Россия, Москва
Код внутреннего цикла (с метки 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
3423
г. Чехов
Выложу сюда код, который я подсовываю в 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, Супермодераторы



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

Сейчас этот форум просматривают: Geen


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

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