- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
#include <iostream>
using namespace std;
void enable_misalignment_access_check(){
cout<<"begin "<<__FUNCTION__<<endl;
__asm__(
"pushf\n"
"orl $(1<<18),(%esp)\n"
"popf\n"
);
cout<<"end "<<__FUNCTION__<<endl;
}
void alignedAccess(volatile unsigned char foo[])
{
cout<<"begin "<<__FUNCTION__<<endl;
volatile int t = *(int *)(foo);
cout<<"end "<<__FUNCTION__<<endl;
}
void unalignedAccess(volatile unsigned char foo[])
{
cout<<"begin "<<__FUNCTION__<<endl;
volatile int t = *(int *)(foo+1);
cout<<"end "<<__FUNCTION__<<endl;
}
unsigned char foo[] = { 1, 2, 3, 4, 5, 6 };
int main(void)
{
alignedAccess(foo);
unalignedAccess(foo);
enable_misalignment_access_check();
alignedAccess(foo);
unalignedAccess(foo);
return 0;
}
LispGovno 26.01.2014 02:08 # 0
bormand 26.01.2014 06:36 # +3
Пока в голову приходят только #pragma pack(1) и извраты с кастами char* в указатели на что-то более крупное.
LispGovno 26.01.2014 11:20 # +4
defecate-plusplus 26.01.2014 11:39 # +3
LispGovno 26.01.2014 11:54 # +1
То, что ты сейчас увидишь - в этом тоже велосипеды виноваты (не дождались из-за великов):
https://pp.vk.me/c540101/v540101687/9b20/l8cH679aVPY.jpg
bormand 26.01.2014 12:32 # +1
LispGovno 26.01.2014 12:37 # 0
bormand 26.01.2014 12:44 # +1
Ты так говоришь, как-будто это что-то плохое.
> Я думал кресты по стандарту в конец структур не дописывают мусор.
Я тоже так думал, и боялся за массивы. Но как оказалось - массивы тоже будут ровными и шелковистыми. А в стандарте этот момент я не читал...
Кстати, а у вижуалки как с этим?
LispGovno 26.01.2014 13:02 # +1
скимпилировалось без нареканий
Abbath 26.01.2014 16:44 # 0
WGH 26.01.2014 17:37 # +6
Dummy00001 26.01.2014 23:53 # +2
Этот момент описывается не в крестах. Это имплементэйшн дефайнед - другими словами "ABI".
LispGovno 27.01.2014 01:11 # 0
Dummy00001 27.01.2014 01:18 # +3
TarasB 26.01.2014 12:34 # 0
Мои велосипеды не имеют аналогов в STL. Вернее, один имеет, но только в STL сипипоха, а не в моём.
LispGovno 26.01.2014 12:39 # 0
LispGovno 26.01.2014 13:30 # +5
Hardcode успокоился, TarasB прилёг рядом с ним, и так вместе они читали стандарт языка. Последним остался Kartonagnick. У него вдруг подогнулись ноги, и он рассердился на себя.
— Неслыханно, — пробурчал Kartonagnick. — TarasB знает кресты, а Kartonagnick боится!
С этими словами он перелистнул страницу стандарта. Но ему показалось, что голова у него стала чугунная, и охватила его такая тьма, что даже он, Kartonagnick, без страха измеривший глубочайшие подвалы языка, вдруг попросил всё это развидеть.
Это намек на то, что Тарас знает кресты или намек на то, что Хардкод - кавказец? А насколько у него жесткий?
Что-за цитата? Я со школы ничего не читал.
TarasB 26.01.2014 14:41 # +6
bormand 26.01.2014 14:50 # +5
inkanus-gray 26.01.2014 15:18 # +2
1. Сам удалил пост — можно попытаться уложиться в лимит времени на редактирование.
2. Сам отругал админов — пишешь красным от имени админа причину удаления, потом пишешь ответ.
3. Сам себя забанил — сменил пароль.
Ну вроде всё возможно.
TarasB 26.01.2014 15:19 # +3
inkanus-gray 26.01.2014 15:25 # +2
kegdan 26.01.2014 16:09 # +4
eth0 26.01.2014 17:46 # +6
(Простите за мой любимый вид комментария.)
kegdan 26.01.2014 17:58 # +2
Vindicar 29.01.2014 14:01 # +1
LispGovno 01.02.2014 18:51 # 0
kegdan 01.02.2014 18:56 # +1
LispGovno 01.02.2014 20:36 # 0
kegdan 02.02.2014 03:35 # 0
bormand 26.01.2014 11:45 # +2
LispGovno 26.01.2014 11:52 # 0
bormand 26.01.2014 12:00 # +1
Сейчас попробую крешдамп собрать и посмотреть на него.
bormand 26.01.2014 12:03 # +1
LispGovno 26.01.2014 12:09 # 0
через std::align выровнять можно буфер заведомо большего размера
bormand 26.01.2014 12:26 # +3
А нету :(
Да там питушня полнейшая. Можно даже ничего не выводить, тупо включить AC и выйти. После чего сразу же пидорасит кишки libc с тем самым bus error...
Короче не хочу я с этим связываться, пускай гейдевовцы сами разбираются со своей проверкой.
P.S. А вот на ARM'овских линухах таких проблем быть не должно, там то поди все выравнивания вылизаны.
LispGovno 26.01.2014 12:32 # 0
Может тогда компилятор староват? Они небось пока в стандарт не ввели С++11, то о выравнивании не сильно заботились. Может ключики нужно указать на выравнивание? А вообще гейдевовцы обычно VirtualAlloc вызывают, что бы на границу параграфа (16 или сколько там нужно для ссе) было выравнено. В линуксе должно быть похожее. Кстати, за это тоже хочется убить.
bormand 26.01.2014 12:38 # +1
Там походу какое-то горе от ума, ибо тот же __memcpy_sse2 падает не на sse'шной команде, а на вполне безобидном в обычном режиме муве: mov (%rsi), %ecx
bormand 26.01.2014 12:56 # +2
Либо программист отвечает за alignment'ы входного и выходного буфера, либо придется копировать по одному символу (можно, конечно, в ряде случаев копировать по 4 или по 8 вместо 16, но производительность будет уже не та...), либо насрать на выравнивания, и делать так, как это сделано сейчас ;(
LispGovno 26.01.2014 13:04 # 0
Это худший случай.
bormand 26.01.2014 13:09 # +1
Если же разность адресов не кратна - придется копировать меньшими блоками, т.к. ты никогда не выровняешь оба буфера под нормальное 16-байтное копирование. Либо один удачно встанет, либо второй, но не оба сразу.
А сейчас на x86 и x86_64 сделано довольно тупо - копируется байт, потом два и т.д. до 8, пока размер копируемого блока не выровняется на 16, а дальше идет блочное копирование (насрав на alignment).
LispGovno 26.01.2014 13:15 # +1
bormand 26.01.2014 13:21 # +2
В одном случае из 16, если об этом не позаботились заранее ;)
LispGovno 26.01.2014 13:24 # +1
bormand 26.01.2014 13:39 # +1
Требоваться то оно не требуется, но с выравниванием всяко будет быстрее, меньше кешлайнов затронет и т.п...
WGH 26.01.2014 19:53 # +1
bormand 26.01.2014 19:57 # 0
Да здесь в memcpy и его друзьях дело. Походу 128 битные загрузки/сохранения даже в невыровненном виде быстрее чем побайтовое копирование. Поэтому libc'шники на x86 и x86_64 и пожертвовали alignment'ом.
P.S. У фряхи же вроде своя сишная либа, не libc?
WGH 26.01.2014 20:10 # 0
bormand 26.01.2014 20:24 # 0
TarasB 26.01.2014 12:26 # +2
TarasB 26.01.2014 12:32 # +2
Я заведу тип {char; T} и разберу случаи равнения на 1,2,4. На остальные пока выдам ошибку компиляции. Мне хватит этого на первое время, но ненадолго. Надеюсь, что вскоре за мной придёт помощь.
bormand 26.01.2014 12:35 # +4
laMer007 04.02.2014 11:22 # 0
kegdan 04.02.2014 11:44 # +2
laMer007 04.02.2014 11:46 # 0
kegdan 04.02.2014 11:46 # 0
bormand 04.02.2014 12:03 # 0
Как было показано выше по треду - первый же memcpy развалит всю эту надежность к хуям. Т.к. невозможно сделать одновременно быстрый и alignment-safe memcpy. Если memcpy работает с AC - значит он копирует все по одному байту, или тебе просто повезло, и оба буфера были хорошо выровнены (что при копировании строк не с начала и их конкатенации - просто случайность).
Так что сойдет разве что для небольших тестов своего кода, которые не затрагивают стандартную либу и не юзают memcpy по невыровненным адресам (читай - не используют строки).
laMer007 04.02.2014 12:08 # 0
bormand 04.02.2014 12:09 # 0
А если тупо потестить свой контейнер на наличие проблем с выравниванием - почему бы и нет.
laMer007 04.02.2014 12:10 # +1