Перейти к содержанию
    

отследить изменение переменной.

и все это для того чтобы сравнить неколько переменных? мне кажется быстрее уж сделать тем же memcmp

Ну и каша у Вас с голове :(. Рано Вам реальным программирванием заниматься :( если не понимаете разницы между преобразованиями типов данных и работой данными. "Все это" НИ ОДНОГО БИТА КОДА НЕ ДОБАВЛЯЕТ. "Вcе это" только ИНСТУКЦИИ компилятору, как ему МАКСИМАЛЬНО эффективно сделать работу при ОНОВРЕМЕННОМ обеспечении читаемомти человеком.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

и все это для того чтобы сравнить неколько переменных? мне кажется быстрее уж сделать тем же memcmp

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

а что можно прямо так ?

(my_struct *) my_arr

Да, конечно. Преобразование типа говорящее компилятору, что там по указателю на самом деле не свалка байтов, а структура. В структуре находися какая-то 32 bit переменая. Осталось только сказать компилятору что бы взял эту переменную.

 

((my_struct *) my_arr)->value_32bit

 

И сделает от это МАСИМАЛЬНО эффективным способом.

Для человеческой читабельности можно спрятать преобразование в макрос, или промежуточную переменную, которую компилятор все равно заоптимизирует.

Получится типа:

 

my_struct->value_32bit

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

понял.спасибо.

Изменено пользователем Herz
Избыточное цитирование

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

сделал листинг ради интереса.

if (new_packet[4] != old_packet[4] || new_packet[5] != old_packet[5] || new_packet[6] != old_packet[6] || new_packet[7] != old_packet[7])

    1db8:    7938          ldrb    r0, [r7, #4]
    1dba:    7933          ldrb    r3, [r6, #4]
    1dbc:    4298          cmp    r0, r3
    1dbe:    d10b          bne.n    1dd8 <PARSER_ParseBlePacket+0x458>
    1dc0:    797a          ldrb    r2, [r7, #5]
    1dc2:    7971          ldrb    r1, [r6, #5]
    1dc4:    428a          cmp    r2, r1
    1dc6:    d107          bne.n    1dd8 <PARSER_ParseBlePacket+0x458>
    1dc8:    79bd          ldrb    r5, [r7, #6]
    1dca:    79b0          ldrb    r0, [r6, #6]
    1dcc:    4285          cmp    r5, r0
    1dce:    d103          bne.n    1dd8 <PARSER_ParseBlePacket+0x458>
    1dd0:    79fa          ldrb    r2, [r7, #7]
    1dd2:    79f3          ldrb    r3, [r6, #7]
    1dd4:    429a          cmp    r2, r3
    1dd6:    d010          beq.n    1dfa <PARSER_ParseBlePacket+0x47a>


    if(*((uint32_t*)&new_packet[4]) != *((uint32_t*)&old_packet[4]))

    1db8:    6878          ldr    r0, [r7, #4]
    1dba:    6873          ldr    r3, [r6, #4]
    1dbc:    4298          cmp    r0, r3
    1dbe:    d010          beq.n    1de2 <PARSER_ParseBlePacket+0x462>


    if(memcmp(&new_packet[4],&old_packet[4],4) != 0)

    1a48:    1d3c          adds    r4, r7, #4
    1a4a:    4620          mov    r0, r4
    1a4c:    1d31          adds    r1, r6, #4
    1a4e:    2204          movs    r2, #4
    1a50:    f005 f8f8     bl    6c44 <memcmp>
    1a54:    b160          cbz    r0, 1a70 <PARSER_ParseBlePacket+0xf0>

 

if(*((uint32_t*)&new_packet[4]) != *((uint32_t*)&old_packet[4])) рулит. в принципе это частный случай более общего - ((my_struct *) my_arr)->value_32bit

 

кстати я тут подумал

такую запись

tempParam.maxFlowRate = (uint32_t)new_packet[0]+((uint32_t)new_packet[1]<<8)+((uint32_t)new_packet[2]<<16)+((uint32_t)new_packet[3]<<24);

 

можно заменить на

tempParam.maxFlowRate = *((uint32_t*)&new_packet[0]);
или
tempParam.maxFlowRate = ((my_struct *) my_arr)->value_32bit

 

или я не прав?

 

вот листинг

tempParam.maxFlowRate = (uint32_t)new_packet[3]+((uint32_t)new_packet[2]<<8)+((uint32_t)new_packet[1]<<16)+((uint32_t)new_packet[0]<<24);
    1e32:    7878          ldrb    r0, [r7, #1]
    1e34:    78bc          ldrb    r4, [r7, #2]
    1e36:    0403          lsls    r3, r0, #16
    1e38:    78fa          ldrb    r2, [r7, #3]
    1e3a:    eb03 2104     add.w    r1, r3, r4, lsl #8
    1e3e:    7838          ldrb    r0, [r7, #0]
    1e40:    188c          adds    r4, r1, r2
    1e42:    eb04 6300     add.w    r3, r4, r0, lsl #24
    1e46:    9317          str    r3, [sp, #92]; 0x5c

tempParam.maxFlowRate = *((uint32_t*)&new_packet[0]);
    1998:    683b          ldr    r3, [r7, #0]
    199c:    9317          str    r3, [sp, #92]; 0x5c

нехилая разница.

Изменено пользователем Jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

можно заменить на

Не можно, а НУЖНО. Нужно давать компилятору нормальные максимально обобщенные задания а не заставлять его жонглировать байтами и битами. Грубо говоря надо стараться давать задание "выкопай яму", а не "возьми лопату, воткни в землю, бери больше, кидай дальше...повтори...". Для этого надо в первую очередь знать язык, ибо на подмножестве языка уровня Эллочки Людоедки, объяснить компилятору нормально не реально.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

if(*((uint32_t*)&new_packet[4]) != *((uint32_t*)&old_packet[4])) рулит. в принципе это частный случай более общего - ((my_struct *) my_arr)->value_32bit
На ARM этот 'частный случай' даст hard fault если адрес new_packet или old_packet не будет кратен 4, а так да, оно рулит :)

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

На ARM этот 'частный случай' даст hard fault...

Не обязательно fault - чаще фигню взятую по выровненному адресу молча возвратит. Зависит от конкретной реализации в ядре сделанной конкретным производителем чипа. Но то, что получится нерабочий код это точно.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не обязательно fault - чаще фигню взятую по выровненному адресу молча возвратит. Зависит от конкретной реализации в ядре сделанной конкретным производителем чипа. Но то, что получится нерабочий код это точно.

 

Таки коллективный разум все еще считает себя умнее и быстрее правильно заинлайненного memcmp ? :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

:)

К чему эта улыбочка? Для начала попробуйте сделать этот самый "правильно заинлайненый". Для начала этого сделать просто не удастся - это библиотечная функция. Посему посморите просто на исходник memcmp() дабы, даже если ее заинлайтить, понять написанную Вами глупость.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

К чему эта улыбочка? Для начала попробуйте сделать этот самый "правильно заинлайненый". Для начала этого сделать просто не удастся - это библиотечная функция. Посему посморите просто на исходник memcmp() дабы, даже если ее заинлайтить, понять написанную Вами глупость.

 

Я делаю так:

1. пишу memcmp

2. компилирую в release c соответствующими опциями оптимизации.

3. все

 

Например, такая вот глупая функция:

int Foo_cmp(const void* apSrc, size_t aNumBytes)

{

unsigned char buf[100] = "abcdef";

return memcmp(apSrc, buf, aNumBytes);

}

 

компилируется в следующий кусок ассемблерной хрени:

    
return memcmp(apSrc, buf, aNumBytes);
0134103E  mov         esi,0Fh  
01341043  lea         ecx,[ebp-68h]  
01341046  mov         edx,offset string "qweqweqweq" (13420FCh)  
0134104B  jmp         Foo_cmp+50h (1341050h)  
0134104D  lea         ecx,[ecx]  
01341050  mov         eax,dword ptr [edx]  
01341052  cmp         eax,dword ptr [ecx]  
01341054  jne         Foo_cmp+68h (1341068h)  
01341056  sub         esi,4  
01341059  add         ecx,4  
0134105C  add         edx,4  
0134105F  cmp         esi,4  
01341062  jae         Foo_cmp+50h (1341050h)  
01341064  test        esi,esi  
01341066  je          Foo_cmp+0B9h (13410B9h)  
01341068  movzx       eax,byte ptr [edx]  
0134106B  movzx       edi,byte ptr [ecx]  
0134106E  sub         eax,edi  
01341070  jne         Foo_cmp+0A3h (13410A3h)  
01341072  cmp         esi,1  
01341075  jbe         Foo_cmp+0B9h (13410B9h)  
01341077  movzx       eax,byte ptr [edx+1]  
0134107B  movzx       edi,byte ptr [ecx+1]  
0134107F  sub         eax,edi  
01341081  jne         Foo_cmp+0A3h (13410A3h)  
01341083  cmp         esi,2  
01341086  jbe         Foo_cmp+0B9h (13410B9h)  
01341088  movzx       eax,byte ptr [edx+2]  
0134108C  movzx       edi,byte ptr [ecx+2]  
01341090  sub         eax,edi  
01341092  jne         Foo_cmp+0A3h (13410A3h)  
01341094  cmp         esi,3  
01341097  jbe         Foo_cmp+0B9h (13410B9h)  
01341099  movzx       eax,byte ptr [edx+3]  
0134109D  movzx       ecx,byte ptr [ecx+3]  
013410A1  sub         eax,ecx  
013410A3  sar         eax,1Fh  
013410A6  pop         edi  
013410A7  or          eax,1  
013410AA  pop         esi  

 

В debug версии да, стоит честный вызов memcmp

Изменено пользователем CrimsonPig

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для начала попробуйте сделать этот самый "правильно заинлайненый". Для начала этого сделать просто не удастся - это библиотечная функция.
Не всегда - у gcc например это может быть intrinsic функция компилятора (если ему включить оптимизацию, конечно)

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не всегда - у gcc например это может быть intrinsic функция компилятора (если ему включить оптимизацию, конечно)

Договорились. Пререходим к следующему шагу - используем GCC и его intrinsic, получаем результат и сравниваем с:

 if(*((uint32_t*)&new_packet[4]) != *((uint32_t*)&old_packet[4]))
    1db8:    6878          ldr    r0, [r7, #4]
    1dba:    6873          ldr    r3, [r6, #4]
    1dbc:    4298          cmp    r0, r3

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Договорились. Пререходим к следующему шагу - используем GCC и его intrinsic, получаем результат и сравниваем с:

 

memcmp - то гарантированно работает с невыравненными данными.

Если есть 100% гарантия, что данные выравнены, то и заинлайненная memcmp из библиотеки будет на 3 инструкции.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...