LINUX.ORG.RU

Как выбрать endianness?


0

0

Нужно сохранить в файл много целых чисел, кроссплатформенно.

За Big endian то, что это сетевой порядок байт, вроде как он считается платформонезависимым.

За Little endian то, что он чаще встречается, и накладных расходов на перекодирование не будет (скорость важна).

Что правильнее?

★★★★

Последнее исправление: unsigned (всего исправлений: 1)

Правильнее делать «неродной» порядок байт - big endian, если ты на x86. Чтобы все баги с поворотом байтов сразу вылезали.

tailgunner ★★★★★
()

> Что правильнее?

текстом. не во всех процах 8-битные байты и two's-complement представление отрицательных чисел.

arsi ★★★★★
()

Little endian т.к. чаще встречается.

Тебе реально это надо кроссплатформенно и ты БУДЕШЬ запускать на других архитектурах или просто захотел понтануться кроссплатформенностью? Потому что если тебе важна скорость CPU то вряд ли ты будешь гонять программу, скажем, на arm.

И есть сомнения что накладные расходы при конвертировании будут действительно большими по сравнению с io. Всё равно всё упрётся в диск.

true_admin ★★★★★
()

>Что правильнее?

тут есть два мнения :)

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

Должна быть возможность запускать это везде, в этом одна из фишек программы, в этом понт )

Насчет расходов, вероятно, верно. Там вообще сложная инициализация. Буду еще профилировать, когда напишу.

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

> датасет большой, это его ешё больше раздует, причём в разы.

за кроссплатформенность приходится платить, да.

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

> не во всех процах 8-битные байты

Не должно помешать, у меня только типы stdint.h

> и two's-complement представление отрицательных чисел

А вот это непонятно, я считал, что это стандартизовано.

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

> Надо уточнить: это не просто массив чисел, структура сложная, и не только числа.

тем более. и уточни ещё точнее.

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

> Не должно помешать, у меня только типы stdint.h

наивный :) и какие же типы ты оттуда используешь?

> А вот это непонятно, я считал, что это стандартизовано.

конечно стандартизировано, как и несколько других представлений ;)

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

>> А вот это непонятно, я считал, что это стандартизовано.

конечно стандартизировано, как и несколько других представлений ;)

А давай конкретнее? Например, озвучь список архитектур, на которых двоичные числа представляются _не_ как two's-complement.

Да, и список архитектур, на которых байт не 8-битовый?

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

> А давай конкретнее?

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

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

>> А давай конкретнее?

чего тебе дать?

См. выше

пойди сам возьми

Уже сходил. Твои умствования насче байтов не по 8 бит и двоичных чисел не в two's complement - просто надувание щек (при том, что такие архитектуры существуют). Так что будь скромнее.

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

> и какие же типы ты оттуда используешь?

Натурально, intX_t, uintX_t. X - 8, 16, 32.

> как и несколько других представлений

Так чего, нет способа бинарно и кроссплатформенно записать целое число?

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

> Натурально, intX_t, uintX_t. X - 8, 16, 32.

intX_t — это опциональные, специфичные для архитектуры типы. на одной архитектуре могут быть int12_t, int24_t, int48_t, и т.д., на другой — только int36_t, на третей вообще могут отсутствовать intX_t.

> Так чего, нет способа бинарно и кроссплатформенно записать целое число?

ну придумай какой-нибудь формат или выбери существующий и напиши кроссплатформенные функции загрузки/сохранения.

arsi ★★★★★
()

сделать в файле одно число фиксированным, писать туда, скажем, 0x12345678, при загрузке читать, если не совпадает с требуемым, перевернуть и снова проверить. Если теперь совпадает - поставить флаг, что все числа нужно переворачивать.

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

Есть, только долго записывать/считывать:

typedef struct{
  uint8_t b1;
  uint8_t b2;
  uint8_t b3;
  uint8_t b4;
} myuint32_t;

myuint32_t uitomy(uint32_t n){
  myuint32_t number;
  number.b1 = n >> 24 && 0xff;
  number.b2 = n >> 16 && 0xff;
  number.b3 = n >> 8  && 0xff;
  number.b4 = n       && 0xff;
  return number;
}

int32_t mytoui(myuint32_t n){
  int32_t number = n.b1<<24 | n.b2<<16 | n.b3<<8 | n.b4;
  return number;
}

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от note173

А ля Byte Order Mark в некоторых кодировках.

А вообще «кроссплатформенность» определяется не конкретно форматом (LE vs. BE), а тем что протокол определен так, что обе стороны его способны записать/прочитать независимо от архитектуры.

Вот BSON (binary json, формат, юзаемый MongoDB) использует Little endian, например. Т.к. подавляющее большинство машин именно такие. Что весьма прагматично. Но способствует написанию кода, который непереносим без правок.

ratatosk
()

Сделай как ZFS - пишется все в нативном порядке байт на любой платформе, при чтении порядок байт меняется, если нужно.

mukoh
()
Ответ на: комментарий от unsigned

Во-первых, я про него и не знал, во-вторых, там то же самое по сути.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от unsigned

>> такие архитектуры существуют

Так в чем претензия

В том, что нужно посмотреть на возможные целевые платформы, и строить программу, исходя из этого, а не исходя из всего теоретически существующего зоопарка (например, ты знаешь, что есть машины с адресуемыми битами? хочешь ли ты их поддерживать?).

они слишком редкие?

За 20 лет работы встретил парочку архитектур с не-8-битовым «байтом»; архитектур с не-two's-complement так сразу и не вспомню (ну, разве что читал о CDC-6600).

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

Ненужный велосипед!

> number.b1 = n >> 24 && 0xff;

number.b2 = n >> 16 && 0xff;

number.b3 = n >> 8 && 0xff;


number.b4 = n && 0xff;



Мало того, что маска в этом случае лишняя, так она еще и данные портит :)

...

Если нужна кроссплатформенность, храню данные в сетевом порядке. Для производительности это некритично (как выше уже отмечали, все упрется в IO), а городить костыли вроде хранения в строковом формате геморройно. Если попадется экзотическая платформа, лучше под нее написать (или найти!) конвертер.

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

>Так в чем претензия, они слишком редкие?

Что-то я не помню, чтобы linux (или windows, или т.д.) поддерживал архитектуры с 7-битными байтами

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

> это опциональные, специфичные для архитектуры типы

Тогда можно использовать int_leastX_t при чтении файла, а формировать его только на нормальных архитектурах.

С другой стороны, ввод-вывод побайтовый, так что проблемы все равно будут. Проще не думать об этом )

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

ОК, я отказываюсь от рынка невосьмибитных байтов )

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

за кроссплатформенность приходится платить

это не кроссплатформенность, это неэффективное хранение данных. Можно хранить в little endian и платить почти не придётся.

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

> PowerPCшные маки ещё не все сломались от старости?

э… яббл отказался от ррс _совсем_? о_О почему-то думал, что интел у них как альтернативная платформа…

arsi ★★★★★
()
Ответ на: Ненужный велосипед! от staseg

Упс, я там вместо битового «И» логическое «И» нарисовал. А с чего это маска - лишняя? Мало ли...

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от arsi

> э… яббл отказался от ррс _совсем_? о_О почему-то думал, что интел у них как альтернативная платформа…

Уже второй релиз макоси выходит intel-only, а производить померписишные маки перестали ещё где-то в 2005 или 2006.

PolarFox ★★★★★
()

кроссплатформенно

Сделай отдельный класс, что-то типа плагина, для (де)сериализации своих целых чисел. На каждой платформе свой плагин.

Если кроссплатформенность - фича, то тогда литл. А вообще не парь мозг. Лучше не делай совсем. Когда реально понадобится - тогда сделаешь.

mi_estas
()

imho если приходится хранить/передавать числа в бинарном виде между разными архитектурами, то пусть они будут в сетевом порядке байт.

API конвертации целых чисел для передачи в сеть и обратно:

man 3 endian

man 3 byteorder

p.s. Если у вас там научные/статистические данные, то и хранить их надо в соответственном виде (netcdf и иже с ними). Заодно получая профит в возможности использовать сторонний софт для обсчёта.

MKuznetsov ★★★★★
()

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

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

хз, зависит от самого чипа, наверное. в атмел (ат91), с которым я сейчас работаю, переключалки порядка байт для памяти я не обнаружил (но есть для DMA, LCD и AC97). а в даташите на армовский проц от TI прямо сказано: «ARM Instructions/Data – Little Endian».

arsi ★★★★★
()

А ты уверен, что затык в производительности будет именно из-за перекодирования из big-endian? Да, и ничего плохого нет в том, чтобы использовать little-endian. Платформеннонезависимым бывает _способ_ кодирования, а не сама кодировка.

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

А чего ты его без присмотра оставил?

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

> msgpack

Посмотрю, спасибо. Но на этом проекте это не понадобится.

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