> man operating_systems
Центр информации по операционным системам :: Форумы :: Программирование :: Инструментарий
 
<< Предыдущая тема | Следующая тема >>
inline asm в GCC (i686)... оч.косвенная адресация..
Переход на страницу  [1] 2
Модераторы: Roman I Khimov, Wanderer, Dron
Автор Добавил
vv40in
Понедельник 20.04.2009 18:36
ID пользователя #1076
Зарегистрирован: Суббота 07.06.2008 12:10
Сообщений: 62
весёлого времени сУток!
может здесь кто-н знает конкретный ответ.

дано: 1)регистр (пусть ebx) содержит смещение в массиве. 2)указатель на массив - в стековой переменной (напр. buffer) 3)С-код:
a=buffer[b];

вопрос: как записать в gcc одну (и только одну!!!) команду, чтоб доступисться к содержимому buffer по смещению offset?

я понимаю, что в конце концов это будет выглядеть в листинге примерно так:
movzbl <смещ.buffer.относит.esp>(%esp,%ebx), %eax
но как добиться этого?

__asm__ __volatile__("movl %1,%0" : "=b" (b) : "m" (buffer[inlex]));
не катит, т.к. buffer-уже в регистре. меняется только inlex. да и после операции gcc тупо генерит инструкцию сохранения ebx в b. а это мне не нужно. У меня каждый такт на счету..

__asm__ __volatile__( "movzbl %0(%%ebx), %%eax":: "m"(buffer));
приводит к бреду типа (в листинге):
movzbl <смещ.buffer.относит.esp>(%esp)(%ebx), %eax"
т.е. 2 регистра, и каждый в своих скобках!!!

что делать? не вычислять же смещение <смещ.buffer.относит.esp>!!! как потом сопровождать?! (да и вообще - что за бред это в gcc. В VS указывается смещение относительно ebp. на него хоть можно положиться (в разумных прогах)).

а почему вся затея с inline asm? потому, что gcc не оптимизирует код (или я не знаю еще какие опции для этого). на одной машине код небольошого цикла после gcc(v.4.xx) выпоняется в 1.5 раза медленнее, чем после VSC!!! а судя по коду, gcc вообще не знает , что такое конвейр cpu!

а для с-кода, описанного выше, gcc генерирует аж 2(!!!) asm-команды, в то время, как VSC обходится одной... для очистки конвейра заранее на случай непредсказанного перехода gcc не предпрринимает усилий... и тд

добавил gcc параметр
-fno-guess-branch-probability
и добавил где надо макрос типа likely и __restrict на указатели.
производительность возросла раза в 1.5, но всё ещё на 30% меньше, чем от MSVC2005.

версия gcc:
gcc version 4.2.1 20070719 [FreeBSD]
опции gcc:
-fomit-frame-pointer -W -Wall -march=i686 -fno-guess-branch-probability -std=c99
никакие другие опции дела не меняют.

укажите, пож-ста, путь... (только не оч.далеко
И мож. где-то есть полные доки по inline asm? а то встречаются только какие-то обрывки.

спасибо заранее.
Наверх
Dron
Вторник 21.04.2009 16:29


ID пользователя #13
Зарегистрирован: Понедельник 05.07.2004 11:16
Местонахождение: Москва
Сообщений: 651
У меня нормально сгенерил..

    unsigned char buffer[100];

    for (int i = 0; i < 100; i++) {
        int a = buffer[i];
        printf ("%02x\n", a);
    }

Скомпилилось (тело цикла привожу)

.L2:
        movzbl  (%ebx), %eax
        addl    $1, %ebx
        movl    $.LC0, (%esp)
        movl    %eax, 4(%esp)
        call    printf
        leal    132(%esp), %eax
        cmpl    %eax, %ebx
        jne     .L2


И ясно видно что
int a = buffer[i];
Скомпилилось в
movzbl (%ebx), %eax

Что не так то?

приведи ка функцию и подстрочник... с оптимизацией баловался?

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

Андрей Валяев
Наверх
Сайт
vv40in
Вторник 21.04.2009 18:14
ID пользователя #1076
Зарегистрирован: Суббота 07.06.2008 12:10
Сообщений: 62
спасибо за ответ.
но мне не нужно movzbl (%ebx), %eax
мне нужно исменно так, как я просил
и не оптимизацией. ею ничего не добьешься (см. в пред.посте), по кр мере в gcc3.2 (другой нельзя. неважно по каким причинам. я и сам не знаю. так велено. не обсуждается).
а томко inline asm
__asm__ __volatile__( "movzbl "..." : .. : "???"(buffer), "???"(index));
я уже начал вручную на асме городить всю функцию ... ((

файлы в архиве
Наверх
vv40in
Вторник 21.04.2009 18:20
ID пользователя #1076
Зарегистрирован: Суббота 07.06.2008 12:10
Сообщений: 62
не могу приаттачить файл, хотя его расширение bz2
Наверх
Dron
Среда 22.04.2009 09:43


ID пользователя #13
Зарегистрирован: Понедельник 05.07.2004 11:16
Местонахождение: Москва
Сообщений: 651
Да не нужен мне архив. Но я всетаки склонен полагать, что компилятор тоже оптимизирует хорошо, просто надо правильно написать.

Если ты сформулируешь задачу - можно обдумать как ее правильно закодить.

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

Андрей Валяев
Наверх
Сайт
vv40in
Среда 22.04.2009 10:54
ID пользователя #1076
Зарегистрирован: Суббота 07.06.2008 12:10
Сообщений: 62
можно свести к следующей задаче:
из потока случайных данных мы последовательно читаем 2-3 байта. каждый байт надо перекодировать ч-з 256-символьную таблицу.

вот этот процесс перекодировки символа и должен занимать 1(одну) иструкцию цпу.

вроде всё.

т.е.
symbol=table[symbol]
но table нельзя помещать в регистр, т.к. последовательно перекодируются только 2-3 байта, и для остальных действий тоже нужны регистры, а цпу не резиновый. т.е не катит что-то типа:
leal (table), %ebx
movzbl (%ebx,%eax),%eax
а надо типа:
movzbl <offset>(%esp,%eax),%eax
IMHO,короче и быстрее, согласитесь.

Наверх
vv40in
Среда 22.04.2009 12:26
ID пользователя #1076
Зарегистрирован: Суббота 07.06.2008 12:10
Сообщений: 62
кстати, попробовал интеловским компилятором.
он генерит похожий код. только программа чуть быстрее работает.
Наверх
Dron
Среда 22.04.2009 17:04


ID пользователя #13
Зарегистрирован: Понедельник 05.07.2004 11:16
Местонахождение: Москва
Сообщений: 651
Почему такой упор на использование регистров? ты же на си пишешь?
Кроме того непонятно стремление упихнуть все в 1 инструкицю.
Кстати далеко не факт что movzbl работает быстро.

И не совсем понятно - что есть поток. еще один буфер?
И почему выбирать по 2-3 байта?

Собственно у меня генерит нормальные короткие инструкции, какие тебе нравятся.


int test(unsigned char *buffer, size_t size)
{
    unsigned char table[256];

    for (int i = 0; i < size; i++) {
        int a = buffer[i];
        buffer[i] = table[a];
    }

    return 0;
}

test:
        subl    $256, %esp
        movl    260(%esp), %ecx
        xorl    %edx, %edx
        jmp     .L2
.L3:
        movzbl  (%ecx,%edx), %eax
        movb    (%esp,%eax), %al
        movb    %al, (%ecx,%edx)
        incl    %edx
.L2:
        cmpl    264(%esp), %edx
        jb      .L3
        xorl    %eax, %eax
        addl    $256, %esp
        ret


Не понимаю что тебе не нравится.
Одна инструкция - извлечение из buffer, другая - преобразование через table, третья - возвращение значения в buffer. Куда уж короче то?

Ты можешь почеловечески привести исходник функции, и что где сгенерировалось, с какими флагами?

[ Редактирование Среда 22.04.2009 17:07 ]

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

Андрей Валяев
Наверх
Сайт
vv40in
Четверг 23.04.2009 18:24
ID пользователя #1076
Зарегистрирован: Суббота 07.06.2008 12:10
Сообщений: 62
ну, ладно. пока я уже на inline asm-е всё сделал. но и это не помогло! скорость выполнения программы та же. хотя я взял код MSVC и перенес его в inline asm!
что-то не пойму. может это какие-то системные штучки? т.е. операционка тормозит?
у меня FreeBSD 7.1 на i7 с 6 ядрами .. чепуха
Наверх
ossadchy
Четверг 23.04.2009 22:30
ID пользователя #941
Зарегистрирован: Среда 10.10.2007 22:55
Местонахождение: Украина, Николаевская обл., г. Первомайск
Сообщений: 181
может алгоритм оптимизировать стоит?
откуда сравнение с MSVC -- там быстрей работает? тестируете скорость именно обработки данных без учета IO?
Наверх
Сайт
Переход на страницу  [1] 2  

Перейти:     Наверх

Транслировать сообщения этой темы: rss 0.92 Транслировать сообщения этой темы: rss 2.0 Транслировать сообщения этой темы: RDF
Powered by e107 Forum System

© OSRC.info, 2004-2010.
Авторские права на любые материалы, авторы которых явно указаны, принадлежат их авторам. По вопросам публикации таких материалов обращайтесь к авторам.
Авторские права на любые другие материалы принадлежат OSRC.info.
Сайт является помещением библиотеки. Копирование, сохранение на жестком диске или иной способ сохранения произведений осуществляются пользователями на свой риск.
При использовании материалов сайта ссылка на OSRC.info обязательна.