LINUX.ORG.RU

А как данный код будет выглядеть на сишечке??

 , ,


0

2

Имеется вот такой код:

  ldr     r12, [r0]
  bic     r2, r12, #0xD
  orr     r1, r2, #2
  str     r1, [r0]

А чем это было на сишечке? В голову приходит только

int number;
number = number & 0xfffffff2 | 2;
, но компиляция и последующий objdump выдаёт бредню вида
  ldr     r3, [r7]
  bic     r3, r3, #0xF
  orr     r3, r3, #2
  str     r3, [r7]


А что смущает ? Разные регистры, какие были свободны, такие компилятор и взял и разный мусор в number.

ilovewindows ★★★★★
()

напиши тогда заодно что делают инструкции bic и orr, может чего ответим, а то влом в мануал лезть смотреть

Harald ★★★★★
()
Ответ на: комментарий от Harald

the ORR instruction performs a logical OR operation
the BIC instruction performs an AND NOT operation.

com
() автор топика
Ответ на: комментарий от arturpub

да, я тоже сейчас к такому выводу пришел

ТС, попробуй скомпилировать без оптимизации

Harald ★★★★★
()

Почему же бред? Команд столько же и они такие же (так что скорость будет одинаковая). Зато компилятор смог съэкономить ещё один регистр. Результат исполнения тот же? Если да, то какие претензии к компилятору?

KivApple ★★★★★
()

Вообще судя по тому, как в оригинальном блоке результат раскидался по регистрам, то либо на арме очень дох*я регистров, либо это был очень жестокий -O0, либо же это -O2, но, во-первых, показан только небольшой кусок листинга, а во-вторых, вычисления намного сложнее и в разных частях задействуются промежуточные результаты, бережно сохраненные в r1 и r2.

arturpub ★★
()
Ответ на: комментарий от KivApple

я вот и о смысле такой оптимизации задумался сейчас, вроде бы инструкции те же, в чём профит? Промежуточный регистр r2 вроде бы и в первом случае не нужен был

Harald ★★★★★
()
Ответ на: комментарий от arturpub

и в разных частях задействуются промежуточные результаты, бережно сохраненные в r1 и r2

да, правдоподобное объяснение

Harald ★★★★★
()
Последнее исправление: Harald (всего исправлений: 1)
Ответ на: комментарий от arturpub
int number = getportflags();
int t1 = number & 0xfffffff2;
debug(t1);
return t1 | 2;
arturpub ★★
()
Ответ на: комментарий от com

А первый такой же не смущает ?

Какая-нибудь фигня типа взяли биты, инвертировали, сбросили и другой бит поставили.

x&=~3; //Сброс младших двух битов x|=2; //Установка второго бита

ilovewindows ★★★★★
()
Ответ на: комментарий от Harald

Ммдя. Век живи — век учись. Виновата очень умная IDA. objdump оригинала дал совершенной другой код с другими инструкциями. Всем спасибо!

com
() автор топика

Ох уж эти оптимизации...

Пару дней назад переписал вот этот кусок кода:

        static __inline__ int top_bit(unsigned int bits) {
                int i;

                if  (bits == 0)
                        return -1;
                    i = 0;
                if  (bits & 0xFFFF0000) {
                        bits &= 0xFFFF0000;
                        i += 16;
                }
                if     (bits & 0xFF00FF00) {
                        bits &= 0xFF00FF00; 
                        i += 8;
                }
                if (bits & 0xF0F0F0F0) {
                        bits &= 0xF0F0F0F0;
                        i += 4;
                }
                if (bits & 0xCCCCCCCC) {
                        bits &= 0xCCCCCCCC;
                        i += 2;
                }
                if (bits & 0xAAAAAAAA) {
                        bits &= 0xAAAAAAAA;
                        i += 1;
                }
                return i;
        }

Вот так:

        static __inline__ int top_bit(unsigned int bits) {
                int reg;
                __asm__ __volatile__("clz %0, %1" : "=r"(reg) : "r"(bits));
                __asm__ __volatile__("rsb %0, %1, #31" : "=r"(reg) : "r"(reg));
                return reg;

        }

Последняя строка на asm-е это (31 - reg).

Функция возвращаеть номер первого не нулевого бита или -1, если все биты 0.

Решил проверить насколько возрасла производитебность. Крутил функцию в огромном цикле и мерял время.

Реально времени потратил на то чтоб не дать оптимизатору меня обмануть. Ибо оптимизированный Си-шный код упорно выполнялся быстрее чистого ассемберного.

dvl36
()
Ответ на: Ох уж эти оптимизации... от dvl36

Ибо оптимизированный Си-шный код упорно выполнялся быстрее чистого ассемберного.

И правильно делает. И в большинстве случаев написанный на коленке сишный код будет быстрее написанного на коленке ассемблера.

devl547 ★★★★★
()
Ответ на: комментарий от anonymous

За такой сишный код у нас обычно увольняют в тот же день.

Си-шный код не мой. Вроде бы из «Hackers Delight». Можешь написать код работающий быстрее?

и за «clz», кстати могут тоже, если это арм древнее armv5te.

ARM, разумеется, не древнее. И почему ты думаешь что нет препроцессорной проверки target-а?

dvl36
()
Ответ на: комментарий от devl547

И правильно делает.

На самом деле он выполняеться в 5-6! раз медленнее, если подсунуть случайные вводные данные и не дать оптимайзеру шанса обмануть.

И в большинстве случаев написанный на коленке сишный код будет быстрее написанного на коленке ассемблера.

Что-то не нравиться в моем коде?

Можешь предложить что-то лучше?

dvl36
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.