Форум программистов, компьютерный форум, киберфорум
Наши страницы
С под Linux
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.85/27: Рейтинг темы: голосов - 27, средняя оценка - 4.85
Ultrator
14 / 10 / 1
Регистрация: 28.04.2009
Сообщений: 219
#1

GCC с опцией O3: слово "register" просто игнорируется?

17.05.2009, 14:48. Просмотров 4825. Ответов 45
Метки нет (Все метки)

Сколько ни писал, сколько ни сравнивал - похоже, именно так.
А это действительно так?
(Если да - щас это слово везде затру, а вдруг - нет?)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
17.05.2009, 14:48
Ответы с готовыми решениями:

Напишите функцию expand(s1), заменяющую строку на сокращенную запись. Например, "Иванов" будет заменена на "И-в"
Нуждаюсь в вашей помощи

Для заданного массива из 10 чисел проверить, есть ли в нем два числа, отличающихся ровно на 1, напечатать "да" или "нет"
Для заданного массива из 10 чисел проверить, есть ли в нем два числа,...

GCC Сборка 32 разрядной версии GCC 64 разрядным GCC
Доброго времени суток. Возникла необходимость под 32х разрядный Linux, собрать...

Qt Creator. Все "за" и "против"
Доброго времени суток, форумчане! Сегодня задался вопросом использования такой...

Общение "родных" процессов через неименованый каналы связи
Стояла задача породить потомка fork который в своём теле вызовит exec* и...

45
Vourhey
Почетный модератор
6492 / 2266 / 185
Регистрация: 29.07.2006
Сообщений: 12,534
17.05.2009, 14:57 #2
А разницу покажи между o1 и o3.
1
Ultrator
14 / 10 / 1
Регистрация: 28.04.2009
Сообщений: 219
17.05.2009, 19:09  [ТС] #3
например, вот:
C
1
void simpleinsert(unsigned int N, int *mas)


С O3, (без march):
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
simpleinsert:
    pushl   %ebp
    movl    %esp, %ebp
    pushl   %edi
    movl    8(%ebp), %edi
    pushl   %esi
    movl    12(%ebp), %ecx
    pushl   %ebx
    cmpl    $1, %edi
    jbe .L6
    movl    $1, %esi
    .p2align 4,,7
    .p2align 3
.L5:
    movl    (%ecx,%esi,4), %ebx
    movl    %esi, %eax
    .p2align 4,,7
    .p2align 3
.L4:
    movl    -4(%ecx,%eax,4), %edx
    cmpl    %edx, %ebx
    jge .L3
    movl    %edx, (%ecx,%eax,4)
    subl    $1, %eax
    jne .L4
.L3:
    addl    $1, %esi
    cmpl    %esi, %edi
    movl    %ebx, (%ecx,%eax,4)
    ja  .L5
.L6:
    popl    %ebx
    popl    %esi
    popl    %edi
    popl    %ebp
    ret

C О1:
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
simpleinsert:
    pushl   %ebp
    movl    %esp, %ebp
    pushl   %edi
    pushl   %esi
    pushl   %ebx
    subl    $4, %esp
    cmpl    $1, 8(%ebp)
    jbe .L10
    movl    12(%ebp), %edi
    addl    $4, %edi
    movl    $2, -16(%ebp)
    jmp .L3
.L9:
    addl    $4, %edi
    addl    $1, -16(%ebp)
.L3:
    movl    (%edi), %esi
    movl    -16(%ebp), %eax
    subl    $1, %eax
    je  .L4
    movl    -4(%edi), %ecx
    movl    %eax, %ebx
    cmpl    %ecx, %esi
    jge .L6
    leal    -8(%edi), %edx
    movl    %eax, %ebx
    movl    %edi, %eax
    jmp .L7
.L8:
    movl    (%edx), %ecx
    subl    $4, %eax
    subl    $4, %edx
    cmpl    %ecx, %esi
    jge .L6
.L7:
    movl    %ecx, (%eax)
    subl    $1, %ebx
    jne .L8
.L6:
    movl    12(%ebp), %eax
    movl    %esi, (%eax,%ebx,4)
    movl    -16(%ebp), %eax
    cmpl    %eax, 8(%ebp)
    ja  .L9
    jmp .L10
.L4:
    movl    %esi, (%edi)
    jmp .L9
.L10:
    addl    $4, %esp
    popl    %ebx
    popl    %esi
    popl    %edi
    popl    %ebp
    .p2align 4,,3
    .p2align 3
    ret
С добавлением к O3 опции march, "add/sub 1, exx " заменится на "inc/dec", и только.
А что?

Или Вы имели ввиду что и с О1 также всегда игнорируется?
0
Evg
Эксперт CАвтор FAQ
19278 / 7135 / 528
Регистрация: 30.03.2009
Сообщений: 19,976
Записей в блоге: 30
18.05.2009, 17:07 #4
Модификатор "register" придумали во времена, когда компиляторы были слабые и однопроходные. Это подсказка компилятору, но не более. Большинство современных компиляторов кладут на этот модификатор

Ты всё-таки покажи полный исходник и конкретные строки запуска. А то из того, что ты показал, мало что понятно
1
Ultrator
14 / 10 / 1
Регистрация: 28.04.2009
Сообщений: 219
18.05.2009, 22:49  [ТС] #5
Ну, что собсно показывать...
Суть в том, что хоть при наличии слов "register", хоть после их удаления, код ни одной функции никак не меняется. (-O3, с другими - не знаю)
Вот и думаю - он действительно игнорит их всегда (как и "inline") ?
Просто, в manе об этом ничего не сказано.
Большинство современных компиляторов кладут на этот модификатор
Будем надеяться что это так (хотя ссылка на какой-нибудь официальный док не помешала б...)
0
Evg
Эксперт CАвтор FAQ
19278 / 7135 / 528
Регистрация: 30.03.2009
Сообщений: 19,976
Записей в блоге: 30
18.05.2009, 23:28 #6
Цитата Сообщение от Ultrator Посмотреть сообщение
Будем надеяться что это так (хотя ссылка на какой-нибудь официальный док не помешала б...)
Официальный док - это стандарт языка Си. В нём сказано, что компилятор не обязан распределять переменную на регистр (не в таких словах, но смысл такой). В стандартном Си модификатора inline вроде бы как такового нет - только в Си++ и в более поздних стандартах Си, а так же расширениях Си. по inline компилятор так же н обязан этого делать, однако gcc инлайнит короткие процедуры static inline (если процедуру физически возможно инлайнить). У gcc есть ещё и расширение, когда объекту принудительно навязывается номер регистра - тут он железно распределяет переменную на регистр (опять-таки если это физически ничему не противоречит) - для sparc'а, например, "register int asm ("i0");". Для интела видимо можно указать eax и какие там ещё регистры есть

А твоя проблема-то в чём? Ты хочешь распределить переменную на регистр или чего?

Добавлено через 6 минут 38 секунд
У gcc ещё есть атрибут, когда компилятор обязан инлайнить (если физически невозможно, то будет ругаться)
C
1
void __attribute__((always_inline)) func (void) { ... }
А также атрибут, по которому компилятору запрещено инлайнить
C
1
void __attribute__((noinline)) func (void) { ... }
1
Ultrator
14 / 10 / 1
Регистрация: 28.04.2009
Сообщений: 219
19.05.2009, 10:50  [ТС] #7
"register int asm ("i0");"
А-а... Точно.
Да проблемы собсно и нет, просто руководствуясь этим, во всех своих "реализациях" взял и поудалял слово "register", как ничего не значащее (а ведь так старался, учитывая количество РОН в x86)...
Но затем - подумал, мож зря, как-то жалко стало... Вот и спросил.

Добавлено через 8 минут 10 секунд
Кстати говоря, самое главное-то, забыл сказать...
Вследствии этого (или нет, но не важно), передать аргумент через регистр (а не через стек) (ессно, при условии что он в регистр влезет) - тоже нельзя...
0
Evg
Эксперт CАвтор FAQ
19278 / 7135 / 528
Регистрация: 30.03.2009
Сообщений: 19,976
Записей в блоге: 30
19.05.2009, 12:34 #8
Цитата Сообщение от Ultrator Посмотреть сообщение
Да проблемы собсно и нет, просто руководствуясь этим, во всех своих "реализациях" взял и поудалял слово "register", как ничего не значащее (а ведь так старался, учитывая количество РОН в x86)...
Но затем - подумал, мож зря, как-то жалко стало... Вот и спросил.
Удаляй смело. Компилятор в режиме с оптимизации сам разберйтся, что и куда лучше распределять.

Цитата Сообщение от Ultrator Посмотреть сообщение
Кстати говоря, самое главное-то, забыл сказать...
Вследствии этого (или нет, но не важно), передать аргумент через регистр (а не через стек) (ессно, при условии что он в регистр влезет) - тоже нельзя...
Передача парамтров делается в рамках программных соглашений, которые пишутся на процессор. Обычно эти соглашения на всех операционных системах одинаковые (хотя подозреваю, что где-то кто-то может мухлевать). Наличие модификатора register, насколько я знаю, не влияет на способ передачи аргумента. Для этого используют модифиакторы или атрибуты для функции. В виндовых компиляторах обычно слово __fastcall означает, что параметры по возможности складываются на регистры. У intel'овской версии gcc вроде бы был какой-то атрибут с аналогичным действием
0
Ultrator
14 / 10 / 1
Регистрация: 28.04.2009
Сообщений: 219
19.05.2009, 13:22  [ТС] #9
У intel'овской версии gcc вроде бы был какой-то атрибут с аналогичным действием
О, вот это уже... ближе к телу.
Узнать бы, какой (чтоб прописать его хотя б для функций f(void), а то ведь вообще ...)
0
Evg
Эксперт CАвтор FAQ
19278 / 7135 / 528
Регистрация: 30.03.2009
Сообщений: 19,976
Записей в блоге: 30
19.05.2009, 13:37 #10
Посмотрел исходники gcc-3.4.6
Для 32-битного режима есть атрибуты __attribute__((fastcall)) и __attribute__((regparm(N))), где N - константа
Что конкретно они делают - поэкспериментируй, я в intel'овской системе команд почти ничего не понимаю

> Узнать бы, какой (чтоб прописать его хотя б для функций f(void), а то ведь вообще ...)

Для функции void смысла нет прописывать - там же нет никаких параметров
1
Vourhey
Почетный модератор
6492 / 2266 / 185
Регистрация: 29.07.2006
Сообщений: 12,534
19.05.2009, 13:41 #11
По поводу register. Я делаю так:
C
1
2
  register int *foo asm ("ebx");
  *foo = 5;
И без опций оптимизации сразу будет виден результат:
Assembler
1
0x080483b3 <main+15>:   movl   $0x5,(%ebx)
Без слова register и указания регистра, адрес в памяти будет вычисляться арифметически. В примере выше EBX хранит явный адрес этой перменной в памяти. Да работа, скорее всего, будет с eax вестись в таком случае.
0
Ultrator
14 / 10 / 1
Регистрация: 28.04.2009
Сообщений: 219
19.05.2009, 16:49  [ТС] #12
Посмотрел исходники gcc-3.4.6
Вот это да...Респект!
Для 32-битного режима есть атрибуты __attribute__((fastcall)) и __attribute__((regparm(N))), где N - константа
Спасибо.
Значит, буду экспериментировать.

Не по теме:

А по поводу (void) - я ж не просто так это сказал... Хотя, может, т.к. у нас разные архитектуры...
Но у меня - всё равно, и для (void), делает стандартный (и совершенно бессмысленный) пролог и эпилог (щас выложу код).



Добавлено через 14 минут 37 секунд
Vourhey, а Вы попробуйте функции (не инлайновой только) передать параметры через регистры. (Похоже, тут уже не получится без "fastcall" и т.д.)
0
Vourhey
Почетный модератор
6492 / 2266 / 185
Регистрация: 29.07.2006
Сообщений: 12,534
19.05.2009, 16:53 #13
Хех. А про регистры и передачу параметров ясно сказано во документации по GNU register, что ты явно ничего не сделаешь. Хоть fastcall, хоть что. Только ассемблер тебе сможет гарантировать, что передача будет через регистры. Все остальные случаи - не факт.
0
Ultrator
14 / 10 / 1
Регистрация: 28.04.2009
Сообщений: 219
19.05.2009, 17:29  [ТС] #14
Пример с функцией типа (void). Все оптимизации, ессно, включены:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>
 
 
void ultrator(void){
int b;
return;
}
 
 
 
int main(){
ultrator();
return 1;
}
Получилось:
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
    .p2align 4,,15
.globl ultrator
    .type   ultrator, @function
ultrator:
    pushl   %ebp
    movl    %esp, %ebp
    popl    %ebp
    ret
    .size   ultrator, .-ultrator
    .p2align 4,,15
.globl main
    .type   main, @function
main:
    leal    4(%esp), %ecx
    andl    $-16, %esp
    pushl   -4(%ecx)
    movl    $1, %eax
    pushl   %ebp
    movl    %esp, %ebp
    pushl   %ecx
    popl    %ecx
    popl    %ebp
    leal    -4(%ecx), %esp
    ret
    .size   main, .-main
Вот они, "пролог и эпилог". (И если чё-то добавлять внутрь ultrator(), они останутся).

Только ассемблер тебе сможет гарантировать, что передача будет через регистры.
Вопрос в том, будет ли она когда-нибудь вообще...
0
Vourhey
Почетный модератор
6492 / 2266 / 185
Регистрация: 29.07.2006
Сообщений: 12,534
19.05.2009, 17:49 #15
А теперь объясни, где тут оптимизация с передачей параметров через регистры? Пустая функция, которая ничего не делает. Объясни весь смысл этой затеи и в чем тут решение? И решение чего?
0
Ultrator
14 / 10 / 1
Регистрация: 28.04.2009
Сообщений: 219
19.05.2009, 18:02  [ТС] #16
Ну смотрите, получается, что даже не передавая ничего, функция всё равно будет совершать стандартный набор действий:
Assembler
1
2
3
 pushl   %ebp
        movl    %esp, %ebp
        popl    %ebp
А попытайтесь чё-то передать, да ещё при этом чтобы этих действий не стало - всё равно это так и останется (а тогда - и смысла нет).
Что за последовательность
pushl %ebp
movl %esp, %ebp
popl %ebp ???
- абсолютная бессмыслица, которая остаётся в любой функции, даже если и удастся его "уговорить" передать её аргумент через регистр. Или как?
0
Vourhey
Почетный модератор
6492 / 2266 / 185
Регистрация: 29.07.2006
Сообщений: 12,534
19.05.2009, 18:08 #17
так это ж стандартный набор инструкций при входе в подпроцедуру. Он обеспечивает тебе то, что ты вернешься из нее правильно. Фигасе, бессмысленный! он сохраняет значения важных ему регистров, например, в стеке.
0
Ultrator
14 / 10 / 1
Регистрация: 28.04.2009
Сообщений: 219
19.05.2009, 18:47  [ТС] #18
А если у меня функция работает только на регистрах, и никаких локальных переменных в стек не кладёт и не удаляет (при работе ф-и, стек вообще не затрагивается) - тогда зачем ? (И убрать это - нельзя.)

И вообще - что писать, чтобы он сделал передачу через регистр ? (А может, у gcc этого просто нет?)
0
Vourhey
Почетный модератор
6492 / 2266 / 185
Регистрация: 29.07.2006
Сообщений: 12,534
19.05.2009, 18:52 #19
Assembler
1
2
3
4
pushl   %ebp ; сохраняю содержимое %ebp
movl    %esp, %ebp ; вместо регистра указателя стека буду юзать %ebp
;код самой функции
popl    %ebp ; восстанвливаем %ebp.
Блин, я тебя вообще не пойму. Через какой регистр тебе нужно? Какая передача? Чего? У тебя функции ничего не передается. Напиши ассемблерным кодом, че ты хочешь получить. Вот я вообще не жалуюсь на код выше. Не понимаю, что тебе не нравится в нем.
Если ты хочешь лучшую оптимизацию - редактируй бинарь, в чем проблема-то. А стандартный код пусть пишет, не нужно его удалять.

Добавлено через 2 минуты 26 секунд
А если у меня функция работает только на регистрах, и никаких локальных переменных в стек не кладёт
Ну и ладно. Работа в функции идет с регистрами, стек не трогаем. В чем компилер-то виноват?
0
Evg
Эксперт CАвтор FAQ
19278 / 7135 / 528
Регистрация: 30.03.2009
Сообщений: 19,976
Записей в блоге: 30
19.05.2009, 19:58 #20
Цитата Сообщение от Ultrator Посмотреть сообщение
А если у меня функция работает только на регистрах, и никаких локальных переменных в стек не кладёт и не удаляет (при работе ф-и, стек вообще не затрагивается) - тогда зачем ? (И убрать это - нельзя.)
Почитай систему команд на предмет того, как строится операция call. Любой вызов - это как минимум сохранение в стеке адреса возврата, т.е. хочешь ты или нет, при любом вызове всегда используется стек
0
19.05.2009, 19:58
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.05.2009, 19:58

При получения пакета возникает ошибка "Segmentation Fault"
Добрый день! Учился отправлять структуру по сети, натолкнулся на глюк. Если...

Почему глобальные переменные сразу инициализируются "в ноль"?
Доброго времени суток, уважаемые форумчане! Мучает меня один вопрос: Почему...

Компиляция. "Нет такого каталога или файла"
Решил заняться программированием на Си и тут же столкнулся с проблемой, при...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru