использование битов уменьшает затраты на кеш - PullRequest
1 голос
/ 26 марта 2019

Я должен использовать только 5-битные данные MSB из каждых 12-битных данных, я должен брать 64-битные за раз для оптимизации кэша и использовать битовые манипуляции, чтобы получить 5 бит MSB для каждого 12-битного пикселя, я не получаю, Как мне этого добиться? Это код, который я написал и работает правильно, но вместо того, чтобы брать 8 бит за раз (буфер является 8-битным указателем), мне нужно взять 64 бита. В буфере я указал полный файл. * Этот код предназначен для создания гистограммы.

Принимая во внимание LITTLE ENDIAN

1 Ответ

1 голос
/ 26 марта 2019

64 бита не является хорошим кратным 12 битам.Чтобы исправить это, прочитайте группу из трех 64-битных значений (16 пикселей) за раз.Например:

    uint64_t v1 = (uint64_t *)(&buffer[pos]);
    uint64_t v2 = (uint64_t *)(&buffer[pos+8]);
    uint64_t v3 = (uint64_t *)(&buffer[pos+16]);

Затем вы можете сделать всю маскировку сразу:

    v1 &= 0x0F80F80F80F80F80ULL;
    v2 &= 0x80F80F80F80F80F8ULL;
    v3 &= 0xF80F80F80F80F80FULL;

Для первых 5 пикселей просто смещение для разделения значений отдельных пикселей (uint16_t MSBs = v1; v1 >>= 12; повторение 5раз).Для 6-го пикселя вам нужно сделать помадку (MSBs = v2 << 4; v2 >>= 8;), затем для следующих 4 пикселей он вернется к MSBs = v2; v2 >>= 12;, повторяется 4 раза.Для пикселя после этого это немного больше выдумки (MSBs = v2 | (v3 << 8));затем просто MSBs = v3; v3 >>= 12; повторяется 5 раз, чтобы закончить группу из 16 пикселей.

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

...