Comments 13
UFO just landed and posted this here
Стоило включить PGO (profile-guided optimisation) для того, чтобы оптимизация выполнялась для типичного кейса, когда вычисляется сумма 20 слов, а не миллионов.
Для невыравненного доступа к данным мы используем каст в такую структуру
Получается более оптимально, чем с memcpy — компилятор не делает лишнего копирования на архитектурах с невыравненным доступом.
Для невыравненного доступа к данным мы используем каст в такую структуру
struct unaligned_i32 {
int32_t value;
} __attribute__((packed));
Получается более оптимально, чем с memcpy — компилятор не делает лишнего копирования на архитектурах с невыравненным доступом.
+3
Да, кстати вот получается
__attribute__((packed))
решает проблему, а стандартизированный _Alignas(...)
не может выравнять меньше чем на естественную границу.0
Так же: "When used as part of a typedef, the aligned attribute can both increase and decrease alignment...", поэтому можно использовать каст к
typedef uint32_t unaligned_uint32_t __attribute__((aligned(1)));
0
Вместо того чтобы скрывать особенности архитектуры компилятор выворачивает их мехом наружу.
Вот за это современный C++ мне не нравится
+1
uint64_t sum(const char * p, size_t nwords)
{
uint64_t res = 0;
uint64_t data[4] = 0;
size_t i = 0;
while(i < nwords*4)
{
data[0] += (uint64_t)p[i++];
data[1] += (uint64_t)p[i++];
data[2] += (uint64_t)p[i++];
data[3] += (uint64_t)p[i++];
}
res = (data[3] << 24) + (data[2] << 16) + (data[1] << 8) + data[0];
return res;
}
Может и не оптимально, зато весело :-D
0
Вот только это не везде сработает. Т.к. (uint64_t)p[i++]
— разыменование невыравненного указателя
0
Вообще-то это приведение char к uint64_t, а не работа с указателями. Можно и без этого наверное — компилятор сам должен привести если к uint64_t прибавляем char.
И да, ошибочка, объявлять надо так:
И да, ошибочка, объявлять надо так:
uint64_t sum(const unsigned char * p, size_t nwords)
Иначе при преобразовании отрицательных char получится не то, что хотелось бы.0
for (size_t i = 5; i < size / 4; i++) {
sum += q[i];
Предполагается, что размер заголовка всегда кратен 4?
А по поводу использования инструкций sse.
Недавно у себя при сборке проекта clang'ом 3.8 под x86 также на это наступили.
clang в случае зануления через memset активно использует sse.
Временно решили проблему, используя опцию -mstackrealign
0
Жаль, что в ipv4 контрольная сумма не crc32. Т.к. специально для этого существует отдельная инструкция.
0
Удивляет, что выравнивание до сих пор отвратительно стандартизировано даже в новейших редакциях C++. И это при том, что почти любые SSE-инструкции требуют выровненных данных. Зато всякий бред из помойки под названием boost тащат.
Отправьте уже старпёров из комитета на пенсию, они безнадёжно застряли в 80-х.
Отправьте уже старпёров из комитета на пенсию, они безнадёжно застряли в 80-х.
-1
а один раз скопировать в выровненный буфер, и потом целиком посчитать не?
0
Sign up to leave a comment.
История одного бага: выравнивание данных на x86