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

проблемы с выравниванием ARM7

Жаль, что не сохранил дизасм для неверующих. Замена memcpy на цикл с побайтным присваиванием непонятно куда из непонятно откуда чудесным образом всё починило. :biggrin:

Что ровным счетом ничего не доказывает. Конкретную причину abort'а нашли?

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


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

непонятно куда из непонятно откуда чудесным образом всё починило.

Вот и разбирались-бы с непонятками, а memcpy() это, так сказать, святое :) и при этом достаточно простое, дабы уже лет 30 не содержать ошибок ни в одной из реализаций.

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


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

Вот и разбирались-бы с непонятками, а memcpy() это, так сказать, святое :) и при этом достаточно простое, дабы уже лет 30 не содержать ошибок ни в одной из реализаций.

 

Согласен, что простое... Я и не утверждаю что в memcpy есть ошибка, уверен что такие вещи сто раз отладили. Я вот что пытаюсь донести. Есть пердположение, что компилятор лепит в проект несколько реализаций данной функции, в зависимости от разрядности копируемых данных(байтное, 2байтное и 4байтное)? И стоит ему потерять (в результате действий программиста) атрибут packed для какой-нибудь структуры и он запросто применит пословное копирование вместо побайтного(имеет полное право на оптимизацию). И тут то и случится abort именно внутри memcpy.

 

Моё ИМХО, что в общем случае от абортов нельзя защищаться memcpy. Это всего лишь уменьшит вероятность ошибки, но не устранит причину.

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


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

Есть пердположение, что компилятор лепит в проект несколько реализаций данной функции, в зависимости от разрядности копируемых данных(байтное, 2байтное и 4байтное)?

Реализация одна. Да и какой смысл делать несколько, если использовать их можно будет только когда оба адреса константны?

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


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

Моё ИМХО, что в общем случае от абортов нельзя защищаться memcpy. Это всего лишь уменьшит вероятность ошибки, но не устранит причину.

Странный вывод. Вопрос на самом деле шире - дилемма между скоростью и надежностью:

 

1. *(U32*) xxxx = zz; - это быстро но чревато абортом.

2. memcpy - медленно и надежно, от Align Exception'а - это самая лучшая защита, если скорость не жмет.

 

Сказки про глючный memcpy травить не нужно, т.к. ничто не мешает послать библиотечку куда подальше и написать свой "безглючный" вариант memcpy.

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


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

Моё ИМХО, что в общем случае от абортов нельзя защищаться memcpy. Это всего лишь уменьшит вероятность ошибки, но не устранит причину.

От абортов вообще нельзя защищаться. Их просто не должно быть.

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


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

Сказки про глючный memcpy травить не нужно, т.к. ничто не мешает послать библиотечку куда подальше и написать свой "безглючный" вариант memcpy.

 

Ткните пальцем где я написал, о том что memcpy глючит??? :maniac: Читать мой пост до полного осознания того, что я написал, прежде чем лицом об асфальт возить.

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


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

Ткните пальцем где я написал, о том что memcpy глючит??? :maniac:

вот здесь

Замена memcpy на цикл с побайтным присваиванием непонятно куда из непонятно откуда чудесным образом всё починило.

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


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

Замена memcpy на цикл с побайтным присваиванием непонятно куда из непонятно откуда чудесным образом всё починило.

вот здесь

 

В упор не вижу своих слов... memcpy глючит. Ненадо за меня додумывать.

 

сделал дизасм проекта с memcpy, с несколькими экземплярами memcpy я оказался неправ, но всё равно основное то копирование идёт пословно.

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


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

сделал дизасм проекта с memcpy, с несколькими экземплярами memcpy я оказался неправ, но всё равно основное то копирование идёт пословно.

Ну дык слова-то выровнены. И "сковырнуть" memcpy невыровненными адресами никак нельзя.

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


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

Ну дык слова-то выровнены. И "сковырнуть" memcpy невыровненными адресами никак нельзя.

 

void zuzu(int * to, int const * from)
{
    memcpy(to, from, sizeof(int));
}

 

нужна оптимизация с интрисик.

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


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

Поясните мысль.

 

Тут у меня не на чем сделать листинг, но при оптимизации по скорости с интрисик код получится такой же как от *to = *from, если нужно скопировать 3 int, то код будет такой же как от

 

to[0] = from[0]; to[1] = from[1]; to[2] = from[2];

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


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

в зависимости от разрядности копируемых данных(байтное, 2байтное и 4байтное)?

5, 6, 7, 8, 9...... а еще начинающиеся с 0,1,2,.... а еще заканчивающиеся на 0,1,2,3.... :) :)

Вот, кода реализация в IAR была какая-то тормозная пользовал вместо библиотечной такое

//---------------------------------------------------------------------------
// void *(memcpy)(void *p1, const void *p2, size_t n)
// Copy char p2[n] to p1[n]
//---------------------------------------------------------------------------
memcpy:
        teq      r2,#0                  // Is p1 == 0 ?
        bxeq     lr                     // If p1 == 0, return

        stmdb    sp!,{lr}               // Push return address
        mov      r12,r0                 // Copy pointer p1
        cmp      r2,#8                  // Is buffer long or short?
        ble      byteserial             // Jump if n <= 8

        sub      r3,r0,r1               // Compare pointers p1, p2
        tst      r3,#3                  // Strings aligned same?
        bne      byteserial             // Jump if buffers not aligned


// Both strings are similarly aligned WRT word boundaries.
// At least a portion of the data can be copied an entire
// word at a time, which is faster than copying bytes.
wordserial:
        ands     r3,r0,#3               // Check byte alignment
        beq      wordaligned            // Jump if p1, p2 word-aligned

        rsb      r3,r3,#4               // m = no. of odd initial bytes
        sub      r2,r2,r3               // n = n - m


// If the two buffers do not begin on word boundaries, begin
// by copying the odd bytes that precede the first full word.
preloop:
        ldrb     lr,[r1],#1             // Read byte from source
        subs     r3,r3,#1               // --m (decrement loop count)
        strb     lr,[r12],#1            // Write byte to destination
        bne      preloop                // Loop if more bytes to move


wordaligned:
#if WORDS8_TRANSFER == 1
        movs     r3,r2,asr #5           // Any chunks of 8 words?
        beq      octsdone               // Jump if no 8-word chunks

        and      r2,r2,#0x1F            // Subtract chunks from n
        stmdb    sp!,{r4-r10}           // Save registers on stack


// The strings are long enough that we can transfer at least
// some portion of the data in 8-word chunks.
octloop:
        ldmia    r1!,{r4-r10,lr}        // Load 8 words from source
        subs     r3,r3,#1               // More 8-word chunks to move?
        stmia    r12!,{r4-r10,lr}       // Write 8 words to destination
        bne      octloop                // Loop if more chunks

        ldmia    sp!,{r4-r10}           // Restore registers from stack

octsdone:
#endif
        movs     r3,r2,asr #2           // Any more whole words to move?
        beq      wordsdone              // Jump if no more whole words


// Copy as much of the remaining data as possible one word at
// a time.
wordloop2:
        ldr      lr,[r1],#4             // Read next word from source
        subs     r3,r3,#1               // Decrement word count
        str      lr,[r12],#4            // Write next word to destination
        bne      wordloop2              // Loop while more words to move

wordsdone:
        ands     r2,r2,#3               // Any last bytes to transfer?
        beq      theend                 // Return if already done


// The two strings do not end on word boundaries.
// Copy the remaining data one byte at a time.
byteserial:
        ldrb     lr,[r1],#1             // Read byte from source
        subs     r2,r2,#1               // --n (decrement loop count)
        strb     lr,[r12],#1            // Write byte to destination
        bne      byteserial             // Loop if more bytes to move

theend:
        ldmia    sp!,{lr}               // Return
        bx       lr

 

но всё равно основное то копирование идёт пословно.

Зависит от реализации, пример, когда не только пословно, выше (под ключем WORDS8_TRANSFER)

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


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

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

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

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

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

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

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

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

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