big/little endians - вопросы
От: niXman Ниоткуда https://github.com/niXman
Дата: 15.12.13 20:44
Оценка: 1 (1)
приветствую!

в сабже я полный профан, есличо

нужно в свою библиотечку сериализации добавить возможность преобразовывать сабж.
и тут у меня несколько вопросов:
1. какие типы нужно преобразовывать? все фундаментальные? а как быть со строками?
2. если мне к примеру нужно предоставить данные для клиентов использующих как тот, так и другой порядок — по какому принципу мне решать, какой порядок бит я должен отдавать клиентам? по принципу — каких клиентов больше — такой порядок и отдаем? а остальные клиенты уже на своей стороне конвертят данные в нужный им порядок?
3. где-то в списке рассылки буста говорилось о том, что при конвертировании порядка бит возникает какая-то проблема с float/double типами. кто-то может быть в курсе, что это за проблема и в чем она проявляется?

наверное еще вопросы возникнут походу.

благодарен.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re: big/little endians - вопросы
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 15.12.13 21:06
Оценка: 12 (1) +1
Здравствуйте, niXman, Вы писали:

X>нужно в свою библиотечку сериализации добавить возможность преобразовывать сабж.

X>и тут у меня несколько вопросов:
X>1. какие типы нужно преобразовывать? все фундаментальные? а как быть со строками?

Целые, вещественные — да. Строки — юникод в utf-16, utf-32 и прочие wide char.
Ещё есть хохмы с UUID — часть полей переворачивается, часть — нет.

X>2. если мне к примеру нужно предоставить данные для клиентов использующих как тот, так и другой порядок — по какому принципу мне решать, какой порядок бит я должен отдавать клиентам? по принципу — каких клиентов больше — такой порядок и отдаем? а остальные клиенты уже на своей стороне конвертят данные в нужный им порядок?


Как постановишь, так и будет. Это же решение уровня спецификации.

X>3. где-то в списке рассылки буста говорилось о том, что при конвертировании порядка бит возникает какая-то проблема с float/double типами. кто-то может быть в курсе, что это за проблема и в чем она проявляется?


Она такая же, как с целыми. Например:

$ erl
Erlang R15B03 (erts-5.9.3.1) [source] [async-threads:0] [kernel-poll:false]

Eshell V5.9.3.1  (abort with ^G)
1> <<3.1415926:32/big-float>>.
<<64,73,15,218>>
2> <<3.1415926:32/little-float>>.
<<218,15,73,64>>
The God is real, unless declared integer.
Re: big/little endians - вопросы
От: watchmaker  
Дата: 15.12.13 21:08
Оценка: 12 (1) +1
Здравствуйте, niXman, Вы писали:

X>нужно в свою библиотечку сериализации добавить возможность преобразовывать сабж.


X>1. какие типы нужно преобразовывать? все фундаментальные? а как быть со строками?

utf8 одинаково записывается вне зависимости от порядка байт. Для utf32 на самом деле есть два представления: utf32le и utf32be; у utf16 аналогично.

X>2. если мне к примеру нужно предоставить данные для клиентов использующих как тот, так и другой порядок — по какому принципу мне решать, какой порядок бит я должен отдавать клиентам? по принципу — каких клиентов больше — такой порядок и отдаем? а остальные клиенты уже на своей стороне конвертят данные в нужный им порядок?

Обычно удобно чтобы библиотека отдавала данные в нативном формате. Не всегда так бывает, конечно, но вот уж библиотека сериализации просто обязана так делать. Какая-же это сериализация, если клиент должен заботится о порядке байт?
Или ты об порядке в котором хранить данные вне использующей библиотеке программы? Тут уж выбирай сам — всё равно разница не велика. Вполне нормально позаботится и сделать так, чтобы большинству клиентов не пришлось преобразовывать порядок.

X>3. где-то в списке рассылки буста говорилось о том, что при конвертировании порядка бит возникает какая-то проблема с float/double типами. кто-то может быть в курсе, что это за проблема и в чем она проявляется?

Да не больше там проблем чем с целыми числами. Бывает, например, что endiannes для вещественных и для целых чисел не обязательно совпадают на одной машине. Но это такой же исторический курьёз, как и не little/big представления порядка байт.


X> при конвертировании порядка бит

И почему ты упоминаешь про биты? Обычно endiannes — это про байты.
Если у тебя порядок бит не совпадает, то это скорее аппаратная проблема :) То есть исправить, конечно, можно. Но обычно такая ситуация не встречается.
Re[2]: big/little endians - вопросы
От: niXman Ниоткуда https://github.com/niXman
Дата: 15.12.13 22:00
Оценка:
Здравствуйте, netch80, Вы писали:

N>Ещё есть хохмы с UUID — часть полей переворачивается, часть — нет.

а это что за тип такой?

N>Как постановишь, так и будет. Это же решение уровня спецификации.

я просто подумал, что, к примеру, если у моего сервера 80% — пользователей с x86 архитектурой, то, чтоб не нагружать сервер преобразованиями — отдавать данные в x86 порядке бит. остальные же 20% пользователей будут на своей стороне выполнять преобразования.
или это как-то по другому делается?
но, думается мне, отдавать данные в два потока одновременно — плохая идея.

N>Она такая же, как с целыми. Например:

N>
N>$ erl
N>Erlang R15B03 (erts-5.9.3.1) [source] [async-threads:0] [kernel-poll:false]

N>Eshell V5.9.3.1  (abort with ^G)
1>> <<3.1415926:32/big-float>>.
N><<64,73,15,218>>
2>> <<3.1415926:32/little-float>>.
N><<218,15,73,64>>
N>

эм... а что я тут должен увидеть?
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[2]: big/little endians - вопросы
От: niXman Ниоткуда https://github.com/niXman
Дата: 15.12.13 22:06
Оценка:
Здравствуйте, watchmaker, Вы писали:

W>Или ты об порядке в котором хранить данные вне использующей библиотеке программы?

выше уже объяснил.

W>Вполне нормально позаботится и сделать так, чтобы большинству клиентов не пришлось преобразовывать порядок.

я тоже так подумал.

W>Да не больше там проблем чем с целыми числами. Бывает, например, что endiannes для вещественных и для целых чисел не обязательно совпадают на одной машине. Но это такой же исторический курьёз, как и не little/big представления порядка байт.

с этим вроде понял.

W>И почему ты упоминаешь про биты? Обычно endiannes — это про байты.

да? говорю же — в сабже профан
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re: big/little endians - вопросы
От: SkyDance Земля  
Дата: 15.12.13 22:24
Оценка:
X>3. где-то в списке рассылки буста говорилось о том, что при конвертировании порядка бит возникает какая-то проблема с float/double типами. кто-то может быть в курсе, что это за проблема и в чем она проявляется?

Посмотри на postgresql C connector library (она же pqlib), там как раз все эти грабли заботливо собраны с их OID (OIDTYPES).
Re[2]: big/little endians - вопросы
От: niXman Ниоткуда https://github.com/niXman
Дата: 15.12.13 22:29
Оценка:
Здравствуйте, SkyDance, Вы писали:

SD>Посмотри на postgresql C connector library (она же pqlib), там как раз все эти грабли заботливо собраны с их OID (OIDTYPES).

что я там должен посмотреть?
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[3]: big/little endians - вопросы
От: SkyDance Земля  
Дата: 15.12.13 23:09
Оценка:
X>что я там должен посмотреть?

На типы, которые требуют изменения endian-ness, и на их float/double конверсии.
Re[4]: big/little endians - вопросы
От: niXman Ниоткуда https://github.com/niXman
Дата: 15.12.13 23:10
Оценка:
Здравствуйте, SkyDance, Вы писали:

SD>На типы, которые требуют изменения endian-ness, и на их float/double конверсии.

это равносильно предложению "посмотрите исходники в интернетах"
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re: big/little endians - вопросы
От: MTD https://github.com/mtrempoltsev
Дата: 16.12.13 06:47
Оценка:
Здравствуйте, niXman, Вы писали:

X>нужно в свою библиотечку сериализации добавить возможность преобразовывать сабж.


Если нет требований обеспечить максимальное быстродействие, то сериализуй в XML в кодировке utf-8.

Плюсы:
1. Нет проблем с порядком байт
2. Легко изменять и дополнять формат не ломая совместимости
3. Можно просто открыть блокнотом, чтобы посмотреть или поправить значения

Минусы:
1. Скорость
2. Размер

Но несмотря на минусы, в 90% удобство перевесит.
Re[2]: big/little endians - вопросы
От: niXman Ниоткуда https://github.com/niXman
Дата: 16.12.13 07:21
Оценка:
Здравствуйте, MTD, Вы писали:

оно у нас так и было(ну почти так, ибо сериализовали просто в текст).
теперь уже расходы на сериализацию огромны, откладывать некуда.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[3]: big/little endians - вопросы
От: AleksandrN Россия  
Дата: 16.12.13 07:39
Оценка:
Здравствуйте, niXman, Вы писали:

X>я просто подумал, что, к примеру, если у моего сервера 80% — пользователей с x86 архитектурой, то, чтоб не нагружать сервер преобразованиями — отдавать данные в x86 порядке бит. остальные же 20% пользователей будут на своей стороне выполнять преобразования.

X>или это как-то по другому делается?

Существует понятие "сетевой порядок байт". Это big-endian. Его и используй. Для преобразования есть функции htons() — преобразование из хостового в сетевой порядок байт для uin16_t и ntohs() — обратное преобразование. А так-же есть htonl()/ntohl() — преобразование для uint32_t.
Re: big/little endians - вопросы
От: Хреннос  
Дата: 16.12.13 07:40
Оценка: 77 (2)
Здравствуйте, niXman, Вы писали:

X>нужно в свою библиотечку сериализации добавить возможность преобразовывать сабж.


Неверная формулировка — залог неуспеха.
Мне почему-то кажется, что вам нужно не "преобразовывать сабж", а обеспечить единый формат сериализованных данных для платформ с различным порядком байт. Ы?

X>и тут у меня несколько вопросов:

X>1. какие типы нужно преобразовывать? все фундаментальные? а как быть со строками?

Ответ очевиден: преобразовывать нужно те данные, которые в разных архитектурах хранятся по-разному.
К примеру, преобразовывать char, скорее всего, не придется (он и так однобайтовый). А вот short, int и long придется переконвертировать (например, функциями htons, htonl).

Со строками нужно быть предельно осторожным и учитывать формат сериализации. Если перед данными строки вы пишете ее длину — нужно проследить, чтобы длина писалась в едином формате. Данные строки, скорее всего, конвертировать не нужно (если строка в байтовой кодировке типа ASCII или UTF-8). Если строка в юникоде, то нужно следить, чтобы символы юникода писались в правильном формате.

X>2. если мне к примеру нужно предоставить данные для клиентов использующих как тот, так и другой порядок — по какому принципу мне решать, какой порядок бит я должен отдавать клиентам? по принципу — каких клиентов больше — такой порядок и отдаем? а остальные клиенты уже на своей стороне конвертят данные в нужный им порядок?


Конвертация данных через стандартные функции htons/htonl — операция весьма быстрая. На интеловских процах она сводится к одной-единственной дополнительной операции (проверено на GCC с оптимизацией -O2). На биг-ендиан системах, соответственно, эти функции вообще ни в какой код не транслируются.
Так что я бы не парился и сериализовал данные в сетевом формате байт (т.е., биг-ендиан).

X>3. где-то в списке рассылки буста говорилось о том, что при конвертировании порядка бит возникает какая-то проблема с float/double типами. кто-то может быть в курсе, что это за проблема и в чем она проявляется?


Есть мнение, что флоаты лучше вообще не писать в бинарном формате, если хочется переносимости данных. Форматы флоатов, несмотря на существование стандартов, могут быть разными в зависимости от используемого железа и даже опций компиляции. Впрочем, на практике все не так уж и плохо, и флоаты таки активно пишут и читают в бинарном виде. Правда, для "переворота" байт придется, скорее всего, самописный лисапет нарисовать.

А вот порядок битов в структурах на биг- и литтл-ендиан системах действительно может быть разным. Имеется в виду не абстракция ("где в байте самый старший бит"), а конкретика: в каком порядке компилятор отводит биты для структур с битовыми полями. Например, для такой вот структурки:

struct a {
   int m: 1,
   int n: 2,
   int p: 3
};


ГЦЦ под Интелом отведет биты, начиная с LSB: 00pppnnm (два старших бита нулевые — паддинг).
Под биг-ендиан системой (например, SPARC), компилятор начнет отводить биты, начиная с MSB: mnnppp00.
Заметим, что различается только место расположения полей в байтах; биты внутри полей всегда идут в "нормальном" порядке. То есть, скажем, если в p записать число 3 (011 в бинарном виде), то в байте оно будет выглядеть так:
00011nnm (интел)
mnn01100 (спарк)

Соответственно, при записи-чтении битовых полей нужно предусмотреть их преобразование в единый формат. Сделать это на уровне библиотеки сериализации можно, но муторно. Проще вообще отказаться от сериализации структур с битовыми полями.
Re: big/little endians - вопросы
От: MTD https://github.com/mtrempoltsev
Дата: 16.12.13 07:41
Оценка:
Здравствуйте, niXman, Вы писали:

X>1. какие типы нужно преобразовывать? все фундаментальные?


Когда я решал такую задачу, то поддерживать все типы оказалось довольно проблематично, в том числе и из-за разной длины в байтах на разных платформах. Поэтому я упростил задачу сведя все типы к нескольким основным: целое 8 байт, целое со знаком 8 байт, unix time 8 байт, double IEEE 754 8 байт, строка.

X>а как быть со строками?


Длина в начале в байтах, затем текст в utf-8.

X>2. если мне к примеру нужно предоставить данные для клиентов использующих как тот, так и другой порядок — по какому принципу мне решать, какой порядок бит я должен отдавать клиентам? по принципу — каких клиентов больше — такой порядок и отдаем? а остальные клиенты уже на своей стороне конвертят данные в нужный им порядок?


Да, нормальный подход.

X>3. где-то в списке рассылки буста говорилось о том, что при конвертировании порядка бит возникает какая-то проблема с float/double типами. кто-то может быть в курсе, что это за проблема и в чем она проявляется?


Храни в IEEE 754 с известным тебе порядом байт, если на платформе формат отличается — конвертируй.
Re[2]: big/little endians - вопросы
От: niXman Ниоткуда https://github.com/niXman
Дата: 16.12.13 07:53
Оценка:
Здравствуйте, Хреннос, Вы писали:

Х>Конвертация данных через стандартные функции htons/htonl — операция весьма быстрая. На интеловских процах она сводится к одной-единственной дополнительной операции (проверено на GCC с оптимизацией -O2). На биг-ендиан системах, соответственно, эти функции вообще ни в какой код не транслируются.

Х>Так что я бы не парился и сериализовал данные в сетевом формате байт (т.е., биг-ендиан).
т.е. предлагаете конвертировать по умолчанию?

Х>Проще вообще отказаться от сериализации структур с битовыми полями.

у нас это сделано проще — каждый мембер такой структуры сериализуется как полный тип мембера.
т.е. для вашего примера сериализация произведется для такого типа:
struct a {
   int m;
   int n;
   int p;
};
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[2]: big/little endians - вопросы
От: Хреннос  
Дата: 16.12.13 07:57
Оценка:
Здравствуйте, MTD, Вы писали:

MTD>Когда я решал такую задачу, то поддерживать все типы оказалось довольно проблематично, в том числе и из-за разной длины в байтах на разных платформах. Поэтому я упростил задачу сведя все типы к нескольким основным: целое 8 байт, целое со знаком 8 байт, unix time 8 байт, double IEEE 754 8 байт, строка.


Кстати да, о различных размерах типов я совсем забыл.

X>>а как быть со строками?


MTD>Длина в начале в байтах, затем текст в utf-8.


Рекомендую топикстартеру не изобретать велосипед, а взять одно из готовых проверенных решений:
— XDR: http://en.wikipedia.org/wiki/External_Data_Representation
— ProtoBuf: http://en.wikipedia.org/wiki/Protocol_Buffers

XDR — сериализует данные в биг-ендиан, весьма жирный (в том смысле, что любая запись занимает не менее 4 байт, и любая запись кратна четырем байтам). Это несет в себе нехилый оверхед для коротких типов (символов, булевых переменных, коротких строк).
ProtoBuf — разработан в недрах гугля, весьма компактен, данные сериализуются в формате литтл-ендиан.
Re[2]: big/little endians - вопросы
От: niXman Ниоткуда https://github.com/niXman
Дата: 16.12.13 07:57
Оценка:
Здравствуйте, MTD, Вы писали:

MTD>Храни в IEEE 754

где-то я уже видел эту аббревиатуру
а что значит "храни"? если сериализация происходит на x86 машине, то флоаты в каком формате?
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[3]: big/little endians - вопросы
От: Хреннос  
Дата: 16.12.13 08:03
Оценка:
Здравствуйте, niXman, Вы писали:

X>Здравствуйте, Хреннос, Вы писали:


Х>>Конвертация данных через стандартные функции htons/htonl — операция весьма быстрая. На интеловских процах она сводится к одной-единственной дополнительной операции (проверено на GCC с оптимизацией -O2). На биг-ендиан системах, соответственно, эти функции вообще ни в какой код не транслируются.

Х>>Так что я бы не парился и сериализовал данные в сетевом формате байт (т.е., биг-ендиан).
X>т.е. предлагаете конвертировать по умолчанию?

Вам решать.
Я всего лишь подчеркнул, что конвертация в сетевой формат данных на интеловских процессорах практически бесплатна: одна дополнительная команда процессора выполняется очень быстро. Какую-то разницу нам удалось обнаружить только в тестах, гоняющих миллиарды преобразований структур (и то различия был в районе 1-2%); в реальном коде влияние конвертации неощутимо.
Кстати, в наших тестах структуры были довольно большими и с битовыми полями внутри (кадры специфических сетевых протоколов).

Х>>Проще вообще отказаться от сериализации структур с битовыми полями.

X>у нас это сделано проще — каждый мембер такой структуры сериализуется как полный тип мембера.

Это правильно.
Re[3]: big/little endians - вопросы
От: MTD https://github.com/mtrempoltsev
Дата: 16.12.13 08:07
Оценка:
Здравствуйте, niXman, Вы писали:

MTD>>Храни в IEEE 754

X>где-то я уже видел эту аббревиатуру

здесь

X>а что значит "храни"? если сериализация происходит на x86 машине, то флоаты в каком формате?


Я double предлагаю. В нем самом.
Re[3]: big/little endians - вопросы
От: niXman Ниоткуда https://github.com/niXman
Дата: 16.12.13 08:12
Оценка:
Здравствуйте, Хреннос, Вы писали:

Х>Рекомендую топикстартеру не изобретать велосипед, а взять одно из готовых проверенных решений:

Х>- XDR: http://en.wikipedia.org/wiki/External_Data_Representation
Х>- ProtoBuf: http://en.wikipedia.org/wiki/Protocol_Buffers

спасибо, но не получится, ибо все наши продукты используют эту сериализацию.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.