AndroidФорумПрограммирование

падение в Native при приведении типов. (2 стр)

Страницы: 1 2 3 Следующая »
#15
16:59, 23 апр 2013

Feo
> progman
> > ради копирования 4х байт вызывать memcpy это дикость о_О
> какая разница, у тебя в любом случае происходит копирование 4х байт.
т.е для копирования 4х байт в int32 ты в своем коде memcpy вызываешь? о_О

Sergio
> не не, я не о том.
ты не понял смысл каста приведенного в посте 1. допустим интересующий меня int лежит со смещением 15 от начала массива.
вот прислал мне сервер 19 байт. первые 15 байт это однобайтовые значения а с 15 по 19 int32 лежит.

Feo
> в данном случае? в том, что бы прострелить себе ногу же ;)
на Интеле указанный каст работает в 16 раз быстрее memcpy и профит только в выигрыше производительности.
можешь посмотреть асм код с memcpy и кастом и сравнить кол-во операций на копирование и их длительность в тактах

#16
17:26, 23 апр 2013

progman
> на Интеле указанный каст работает в 16 раз быстрее memcpy и профит только в
> выигрыше производительности.
но на интеле современные ОС отключают исключение чтения невыровненых данных, поэтому там можно без memcpy
но при этом не стоит забывать про strict aliasing, который на gcc на таком же ровном месте может порождать совершенно некорректный код, хотя стандартом разрешено приведение к char* и от char*

#17
17:28, 23 апр 2013

progman
> на Интеле указанный каст работает в 16 раз быстрее memcpy и профит только в
> выигрыше производительности.
> можешь посмотреть асм код с memcpy и кастом и сравнить кол-во операций на
> копирование и их длительность в тактах
А чё там смотреть то? В обоих случаях, за первую инструкцию происходит копирование значения из памяти в регистр, за вторую инструкцию происходит копирование значения из регистра в память.
Скажу тебе по секрету, реализация оператора присваивания вызывает memcpy (если принять во внимание, что memcpy - платформонезависимый алиас).

progman
> ты не понял смысл каста приведенного в посте 1. допустим интересующий меня int
> лежит со смещением 15 от начала массива.
> вот прислал мне сервер 19 байт. первые 15 байт это однобайтовые значения а с 15
> по 19 int32 лежит.

int x = *(int *)&charbuffer[15];

попробуй такой каст

#18
17:39, 23 апр 2013

Feo
> А чё там смотреть то? [b]В обоих случаях[/b]
дальше можно уже не читать. посмотри HIEW или любым дизассемблером ( IDA Pro например ) код с memcpy и без него - судя по всему будет сюрпрайз для тебя

#19
17:49, 23 апр 2013

progman
Не хочешь копировать или арифметику, смотри армовские доки

This can be avoided using the __packed qualifier:

  __packed uint32_t* pMyPointer = (__packed uint32_t*)(&tmp);

#20
17:56, 23 апр 2013

RPGman
> Не хочешь копировать или арифметику,
да кто сказал что я не хочу?
я лишь привел пример граблей с которыми лично я столкнулся при переносе кода на андроид из windows проекта.
Быстрое присваивание в инт32 дает сбой на ARM и все.
юзать арифметику или memcpy пусть решает каждый сам для себя.

#21
18:09, 23 апр 2013

progman

> Быстрое присваивание в инт32 дает сбой на ARM и все.
Это UB, что же ты хотел. И вообще нарушение правил alignment/aliasing довольно распространенная ошибка.

#22
19:23, 23 апр 2013

Я что-то не очень удивлён падению. Пытаться вытащить int между байтами - какая-то не очень корректная задача, даже при попытке уложить её в голове. Я даже 128-битный struct-объект из массива 32-битных int'ов побоюсь брать по индексу, не кратному четырём. Хотя это, наверняка, как раз-таки корректно.

#23
20:14, 23 апр 2013

Роман Шувалов
> Я что-то не очень удивлён падению. Пытаться вытащить int между байтами -
> какая-то не очень корректная задача
что некорректного интерпретировать 4 байта где то в памяти как int32 число? ( windows на intel )

Ghost2
> И вообще нарушение правил alignment/aliasing довольно распространенная ошибка.
в ем нарушение? стандарт операцию не запрещает. е меня есть кусок памяти я знаю что мне надо вытащить 5 6 7 и 8й байты и интерпретировать их как int32 число
можно сделать memcpy можно арифметически а можно через приведение типа указателя.

или стандарт запрещает char* приводить к int* ??

#24
20:18, 23 апр 2013

progman
> что некорректного интерпретировать 4 байта где то в памяти как int32 число? (windows на intel )
Даже windows на intel имеет пенальти, и будет аналогично падать при установке флажка AC в регистре флагов.

#25
20:25, 23 апр 2013

RPGman
> Даже windows на intel имеет пенальти, и будет аналогично падать при установке
> флажка AC в регистре флагов.
не знал про АС. за 15 лет ни разу не ловил сабж. хотя именно таким приведением постоянно пользуюсь.

#26
22:27, 23 апр 2013
int somefunc (unsigned char* buffer) {
  int ret;
  switch (((unsigned)buffer) % 4) {
    case 0 : ret = *(unsigned*)buffer; break;
    case 1 : ret = (*(unsigned*)(buffer-1) >> 8) | (*(unsigned*)(buffer+3) << 24); break;
    case 2 : ret = (*(unsigned*)(buffer-2) >> 16) | (*(unsigned*)(buffer+2) << 16); break;
    case 3 : ret = (*(unsigned*)(buffer-3) >> 24) | (*(unsigned*)(buffer+1) << 8); break;
  }
  return ret;
}
#27
22:56, 23 апр 2013

Про сабж по идее где только не написано, хотя вот оказывается не все и знают то.
Хотя вообще конечно скотство определенное в этом от производителей процов есть.

#28
23:08, 23 апр 2013

К тому же позиция разработчиков чипов памяти тоже плохо понятна. Т.е. понятно что проблема в том что банки памяти хранятся битовыми массивами так что при текущей схеме обращаться к некой некратной границе приводит к необходимости опросить один и тот же битовый массив дважды - это ясно. А вот что мешает удвоить число этих битовых массивов (при сохранении разрядности шины) так что такая проблема уже не возникает и там тривиальный сдвиг делать - вот это плохо понятно.

#29
23:56, 23 апр 2013

progman

> или стандарт запрещает char* приводить к int* ??
Стандарт говорит, что после приведения разименование указателя это UB, если тип, к которому приводится, имеет более строгие требования к выравниванию.
А не запрещает он такие приведения, потому что твоей целью может быть просто арифметика указателей.

Страницы: 1 2 3 Следующая »
AndroidФорумПрограммирование

Тема в архиве.