Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Обойти математический сопроцессор, оптимизация программы 
:(
    Опции темы
liliputochka
Дата 21.12.2010, 10:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 154
Регистрация: 16.3.2006
Где: Волгоград

Репутация: нет
Всего: нет



Добрый день,
  у меня программа, написанна на С, выполняет простые математические операции с плавающей точкой с помощью математического сопроцессора. Нужно реализовать эти же операции, но так чтобы математический сопроцессор в вычислениях не участвовал. Пробовала перевести числа в формат с фиксированной точкой. К сожалению, функции выполняющие перевод тоже используют математический сопроцессор.
 Подскажите что делать?
PM MAIL   Вверх
Akina
Дата 21.12.2010, 11:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 20
Всего: 454



Взять библиотеку эмуляции сопроцессора из какого-нить древнего языка и выдрать оттуда нужные функции...
А какой смысл НЕ использовать сопр?


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
liliputochka
Дата 21.12.2010, 13:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 154
Регистрация: 16.3.2006
Где: Волгоград

Репутация: нет
Всего: нет



Есть такое мнение, что работа с числами с плавающей точкой занимает больше тактов работы процессора, чем с числами с фиксированной точкой. Надо это мнение проверить.
Не подскажете библиотеку эмуляции сопроцессора? И какой язык можно взять для поиска этой библиотеки?
PM MAIL   Вверх
W4FhLF
Дата 21.12.2010, 15:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


found myself
****


Профиль
Группа: Участник Клуба
Сообщений: 2831
Регистрация: 2.12.2006

Репутация: 5
Всего: 121



Если вы работаете на обычных современных процессорах, то это мнение просто бред.

Это сообщение отредактировал(а) W4FhLF - 21.12.2010, 15:09


--------------------
"Бог умер" © Ницше
"Ницше умер" © Бог
PM ICQ   Вверх
Severyanin
Дата 21.12.2010, 16:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Исследователь
**


Профиль
Группа: Участник
Сообщений: 554
Регистрация: 31.7.2007
Где: Россия, Омск

Репутация: нет
Всего: 9



Нет, это не совсем бред. По-идее, так оно и есть. Просто я не вижу смысла в такой оптимизации на современных процессорах. Опишите задачу, пожалуйста. Наверняка есть более простое и логичное ее решение


--------------------
"Звонким вереском скроются наши следы, и не вспомнят о них. Кто поверит нам, рыцарям павшей звезды из отвергнутых книг? Пусть в узоре времен ни стихов. ни имен, но напомнит забывшим их полуночный крик." Тэм Гринхилл
"Ужели суслик твоего коварства нагадит в плов доверья моего?". Л.Филатов 
PM MAIL WWW ICQ   Вверх
liliputochka
Дата 21.12.2010, 20:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 154
Регистрация: 16.3.2006
Где: Волгоград

Репутация: нет
Всего: нет



Задача проста:
 дана функция, ее надо оптимизировать. При профилировке было замечано, что код использующий математические операции с плавающей точкой работает особенно медленно. Соответсвтвенно было решено оптимизировать эти выражения. Код был заменен на ассемблерный аналог, но выигрыша во времени это не дало. Вот теперь оптимизация добралась до перевода чисел в формат фиксированной точки (8.24).
PM MAIL   Вверх
maxim1000
Дата 21.12.2010, 20:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 3334
Регистрация: 11.1.2003
Где: Киев

Репутация: 33
Всего: 110



если уж дошло до деталей настолько близких к конкретному процессору, то, возможно, есть смысл почитать его сравнительные скорости различных операций на нём

если рассматривать абстрактный процессор, боюсь, на таком уровне оптимизации уже бессмысленны


--------------------
qqq
PM WWW   Вверх
liliputochka
Дата 21.12.2010, 20:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 154
Регистрация: 16.3.2006
Где: Волгоград

Репутация: нет
Всего: нет



Как узнать какой у меня процесссор?
PM MAIL   Вверх
Pavia
Дата 21.12.2010, 20:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 418
Регистрация: 6.12.2008

Репутация: 11
Всего: 12



liliputochka, 
Тогда вопрос о компетентности ассемблерной оптимизации встаёт ребром.

CPU_Z возьми и посмотри. 
А когда будешь оптимизировать используй CPUID .

Что оптимизировали? Какую задачу решали? 

Какая операция самая медленная?

Какие оптимизационные методики использовали? Алгоритм уже оптимизирован? Надеюсь что код уже рассчитан на неравномерный доступ к памяти? Число обращений к памяти уменьшено? А парализация данных уже задействована?  


PM MAIL   Вверх
W4FhLF
Дата 21.12.2010, 22:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


found myself
****


Профиль
Группа: Участник Клуба
Сообщений: 2831
Регистрация: 2.12.2006

Репутация: 5
Всего: 121



Цитата(liliputochka @  21.12.2010,  20:20 Найти цитируемый пост)
При профилировке было замечано, что код использующий математические операции с плавающей точкой работает особенно медленно.


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


--------------------
"Бог умер" © Ницше
"Ницше умер" © Бог
PM ICQ   Вверх
liliputochka
Дата 22.12.2010, 10:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 154
Регистрация: 16.3.2006
Где: Волгоград

Репутация: нет
Всего: нет



Первоначальная функция:
Код

Void SinGen_S_gen_t_sin(ALG_Handle h, float frame[restrict], int size)
{
    SinGen_S_Obj * gen = (Void *)h;

    Uint32 phase, aphase;
    Uint32 reg, kv, sig;
    float S, C, St, Ct, d, cosd, d1, a=0.5, one=1.0, kk=K;
    Uint32 K1;
    Uint32 step;

    reg=  gen->reg;
    step= gen->step;

//    #pragma MUST_ITERATE (1, 256)

    while(size--)
    {        
        sig= (Uint32)((Int32)(reg) >> 31);
        kv= (Uint32)((Int32)(reg << 1) >> 31);

            phase = ((kv ^ (reg << 2)) >> 2) + (kv >> 31);
        aphase = phase >> (32 - 2 - lengchTbl);

        phase = _clr(phase, 32 - 2 - lengchTbl, 31);


        St= gSin_tabl[aphase];
        Ct= gSin_tabl[(1 << lengchTbl) - aphase];

        d = K * phase;

        cosd= 1. - 0.5f*d*d;


        C = Ct * cosd - St * d;
        S = St * cosd + Ct * d;



        S = SET_SIGN_F(S, sig);        // ++--
        C = SET_SIGN_F(C,  sig ^ kv);    // +--+

        S = exp2(-24) * S;
        C = exp2(-24) * C;

        *frame++ = C;
        *frame++ = S;

        reg += step; // mod 32

    }
    gen->reg= reg;
}

Код, который оптимизировали с помощью ассемблера выделен жирным шрифтом.
Ассемблерный код:
Код

        asm("finit");
        asm("flds %0"::"g"(kk));
        asm("fmul %0":"=g"(d):"g"(phase));

        asm("flds %0"::"g"(d));
        asm("fmul %0"::"g"(a));
        asm("fmul %0"::"g"(d));
        asm("fld1");
        asm("fsubrp");
        asm("fstps %0":"=g"(cosd));
    
         asm("flds %0"::"g"(Ct));
        asm("fmul %0"::"g"(cosd));
        asm("flds %0"::"g"(St));
        asm("fmul %0"::"g"(d));
        asm("fsubp");
        asm("fstps %0":"=g"(C));
         asm("flds %0"::"g"(St));
        asm("fmul %0"::"g"(cosd));
        asm("flds %0"::"g"(Ct));
        asm("fmul %0"::"g"(d));
        asm("faddp");
        asm("fsts %0"::"g"(S));

Функция на С уже оптимизированна.

Добавлено через 6 минут и 32 секунды
Вот этот код тратил особенно много процессорного времени:
Код

        d = K * phase;
        cosd= 1. - 0.5f*d*d;
        C = Ct * cosd - St * d;
        S = St * cosd + Ct * d;

PM MAIL   Вверх
W4FhLF
Дата 22.12.2010, 13:42 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


found myself
****


Профиль
Группа: Участник Клуба
Сообщений: 2831
Регистрация: 2.12.2006

Репутация: 5
Всего: 121



Вот то о чём я и говорил.

Цитата(liliputochka @  22.12.2010,  10:40 Найти цитируемый пост)
Вот этот код тратил особенно много процессорного времени:


И чего вы хотели добиться простым переписыванием этого кода на ассемблер? Любой современный компилятор лучше вас оптимизирует код. Забудьте про ассемблер.

А второе очевидно, что в этом коде нет никаких ресурсоёмких операций (типа логарифма или корня), они простейшие и на современных процессорах занимают единицы тактов. Операнды -- простые переменные, которые компилятор кладёт в регистры, в любом случае они кешированы и на доступ к ним время практически не тратится.

У вас тормозит НЕ этот код. А тот, что идёт перед ним:

Код

        St= gSin_tabl[aphase];  \\ <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
        Ct= gSin_tabl[(1 << lengchTbl) - aphase]; \\ <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
        d = K * phase;
        cosd= 1. - 0.5f*d*d;
        C = Ct * cosd - St * d;
        S = St * cosd + Ct * d;


Первые две строки, где вы обращаетесь к памяти занимают больше всего времени. А профайлер вам показывает на следующие строки потому что процессор ждёт пока будут получены значения из памяти. Профайлер это программа и в силу колосальной сложности современных процессоров она не всегда точна (скорее всегда неточна). Нужно понимать, что она показывает и как это на самом деле интерпретируется.

На современных процессорах любое чтение из памяти эквивалентно тысяче сложений/умножений/вычитаний. Вот и подумайте какой смысл оптимизировать арифметику если всего-лишь одно обращение к памяти съест любой прирост производительности вычислений. Вам нужно оптимизировать работу с памятью, вычислить паттерн обращений к таблице gSin_tabl и организовать доступ таким образом, чтобы был эффективно задействован кеш процессора. В идеале следует стремиться к тому, чтобы доступ был последовательным. 

Следует почитать литературу по оптимизации прежде, чем тратить время на всякую ерунду типа переписывания кода на ассемблер или обход сопроцессора. 

Это сообщение отредактировал(а) W4FhLF - 22.12.2010, 13:52


--------------------
"Бог умер" © Ницше
"Ницше умер" © Бог
PM ICQ   Вверх
liliputochka
Дата 22.12.2010, 15:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 154
Регистрация: 16.3.2006
Где: Волгоград

Репутация: нет
Всего: нет



W4FhLF те строки что вы указали в качестве ресурсоемких являются массивом. На сколько я представляю, массив хранится в кеше или оперативке, доступ к которой занимает 1 такт процессорного времени. К тому же стоки, которые я указала как ресурсоемкие были выявлены эмпирически, а не профайлером. Профайлер указал саму функцию.
PM MAIL   Вверх
W4FhLF
Дата 22.12.2010, 17:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


found myself
****


Профиль
Группа: Участник Клуба
Сообщений: 2831
Регистрация: 2.12.2006

Репутация: 5
Всего: 121



Цитата(liliputochka @  22.12.2010,  15:31 Найти цитируемый пост)
На сколько я представляю, массив хранится в кеше или оперативке, доступ к которой занимает 1 такт процессорного времени.


Вы неправильно представляете. 

Какой у вас размер массива?




--------------------
"Бог умер" © Ницше
"Ницше умер" © Бог
PM ICQ   Вверх
Pavia
Дата 22.12.2010, 19:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 418
Регистрация: 6.12.2008

Репутация: 11
Всего: 12



Цитата(W4FhLF @  22.12.2010,  13:42 Найти цитируемый пост)
На современных процессорах любое чтение из памяти эквивалентно тысяче сложений/умножений/вычитаний.

1 так чтение из кэша 14 при кэш промахке+частота процессора/частоту памяти(1-5 такта). Но это не на самых последних. В самых последних видимо уже всё по другому так как частоту памяти уж практически дотянули до частоты процессора.
Умножение выполняется быстро, но не так как хочется. 

Пока в коде еще не разбирался но по первому взгляду скажу тормазят вычисления. Но от таблице лучше отказаться. Рекомендации дам чуть по позже.
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Алгоритмы"

maxim1000

Форум "Алгоритмы" предназначен для обсуждения вопросов, связанных только с алгоритмами и структурами данных, без привязки к конкретному языку программирования и/или программному продукту.


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, maxim1000.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Алгоритмы | Следующая тема »


 




[ Время генерации скрипта: 0.0658 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.