Превратите большой кусок памяти назад, быстро

Scribd больше не требует, чтобы вы размещали документы на своем сервере. Если вы создаете учетную запись с ними, чтобы получить идентификатор издателя. Для загрузки файлов PDF, хранящихся на вашем собственном сервере, требуется всего несколько строк кода JavaScript.

Для получения дополнительной информации см. Инструменты разработчика .

13
задан SF. 28 January 2010 в 10:46
поделиться

7 ответов

Есть классический способ сделать это. Скажем, unsigned int - ваше 32-битное слово. Я использую C99, потому что ключевое слово ограничения позволяет компилятору выполнять дополнительные оптимизации в этом скорости, который в противном случае был бы недоступным. Эти ключевые слова сообщают компилятору, что «SRC» и «DEST» не перекрываются. Это также предполагает, что вы копируете интегральное количество слов, если вы не, то это всего лишь начать.

Я также не знаю, какие битовые переключения / поворота примитивов быстро на руке и которые медленно. Это что-то рассмотреть. Если вам нужна больше скорости, рассмотрите возможность разбирать вывод от компилятора C и отправиться оттуда. При использовании GCC, попробуйте O2, O3, и ОС, чтобы увидеть, какой из них самый быстрый. Вы можете уменьшить киоски в трубопроводе, делая два слова одновременно.

Это использует 23 операции на слово, не подсчитывая нагрузку и хранилище. Однако эти 23 операции все очень быстро, а ни одна из них не доступа к памяти. Я не знаю, будет ли стол поиска быстрее или нет.

void
copy_rev(unsigned int *restrict dest,
         unsigned int const *restrict src,
         unsigned int n)
{
    unsigned int i, x;
    for (i = 0; i < n; ++i) {
        x = src[i];
        x = (x >> 16) | (x << 16);
        x = ((x >> 8) & 0x00ff00ffU) | ((x & 0x00ff00ffU) << 8);
        x = ((x >> 4) & 0x0f0f0f0fU) | ((x & 0x0f0f0f0fU) << 4);
        x = ((x >> 2) & 0x33333333U) | ((x & 0x33333333U) << 2);
        x = ((x >> 1) & 0x55555555U) | ((x & 0x555555555) << 1);
        dest[n-1-i] = x;
    }
}

Эта страница является отличной ссылкой: http://graphics.stanford.edu/~seander/bithacks.html#bitereverseobviouss

Заключительное примечание: Глядя на ссылку на сборку ARM, есть «Rev» OPCode, который меняет порядок байта в слово. Это будет побриться 7 операций на петлю от приведенного выше кода.

22
ответ дан 1 December 2019 в 17:15
поделиться

Самый быстрый способ сохранить обратное всех возможных байтовых значений в таблице поиска. Стол займет всего 256 байтов.

16
ответ дан 1 December 2019 в 17:15
поделиться

Создание таблицы поиска на 256 элементов байтовых значений, которые являются битовыми из их индекса.

{0x00, 0x80, 0x40, 0xc0, и т. Д.}

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

Если вы пишете языку сборки, набор инструкций X86 имеет инструкцию XLAT, которая делает только этот вид поиска. Хотя на самом деле это не будет быстрее, чем C код на современных процессорах.

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

Вот основной код (не включая оптимизацию линии кэша)

// bit reversing lookup table
typedef unsigned char BYTE;
extern const BYTE g_RevBits[256];

void ReverseBitsInPlace(BYTE * pb, int cb)
{
    int iter = cb/2;
    for (int ii = 0, jj = cb-1; ii < iter; ++ii, --jj)
    {
        BYTE b1 = g_RevBits[pb[ii]];
        pb[ii] = g_RevBits[pb[jj]];
        pb[jj] = b1;
    }

    if (cb & 1) // if the number of bytes was odd, swap the middle one in place
    {
       pb[cb/2] = g_RevBits[pb[cb/2]];
    }
}

// initialize the bit reversing lookup table using macros to make it less typing.
#define BITLINE(n) \
   0x0##n, 0x8##n, 0x4##n, 0xC##n, 0x2##n, 0xA##n, 0x6##n, 0xE##n,\
   0x1##n, 0x9##n, 0x5##n, 0xD##n, 0x3##n, 0xB##n, 0x7##n, 0xF##n,

const BYTE g_RevBits[256] = {
  BITLINE(0), BITLINE(8), BITLINE(4), BITLINE(C), 
  BITLINE(2), BITLINE(A), BITLINE(6), BITLINE(E), 
  BITLINE(1), BITLINE(9), BITLINE(5), BITLINE(D), 
  BITLINE(3), BITLINE(B), BITLINE(7), BITLINE(F), 
  };
14
ответ дан 1 December 2019 в 17:15
поделиться

Чтобы перевернуть один байт X, вы можете обрабатывать биты по одному за раз:

unsigned char a = 0;
for (i = 0; i < 8; ++i) {
   a += (unsigned char)(((x >> i) & 1) << (7 - i));
}

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

Тогда вам просто нужно обратить вспять байтовый массив, и когда вы пишете данные, примените вышеупомянутое отображение. Реверсирование байтового массива - это хорошо документированная проблема, например здесь .

2
ответ дан 1 December 2019 в 17:15
поделиться

BIT Twiddling Hackdling сайт ALWAS Хорошая отправная точка для таких проблем. Посмотрите здесь для быстрой реверсии бита. Затем вам до вас, чтобы применить его к каждому байту / слову вашего блока памяти.

Отредактируемое:

Вдохновленные ITRICH EPP-ответом и глядя на набор инструкций , существует RBIT RBIT , который изменяет биты, содержащиеся в реестре. Поэтому, если производительность имеет решающее значение, вы можете рассмотреть вопрос с использованием какого-либо кода сборки.

9
ответ дан 1 December 2019 в 17:15
поделиться

петля через половину массива, преобразования и обмена байтами.

for( int i = 0; i < arraySize / 2; i++ ) {
    char inverted1 = invert( array[i] );
    char inverted2 = invert( array[arraySize - i - 1] );
    array[i] = inverted2;
    array[arraySize - i - 1] = inverted1;
}

Для преобразования используйте предварительно простое таблицу - массив 2 CHAR_BIT ( CHAR_BIT , скорее всего, будет 8) элементы, где в положении «I» результат байта со значением «I» «Инверсия хранится. Это будет очень быстро - один проход - и потребляет только 2 char_bit для таблицы.

3
ответ дан 1 December 2019 в 17:15
поделиться

Одноядерный?

Сколько памяти?

Буферизуется ли дисплей в памяти и отправляется на устройство, или это единственная копия пикселей в памяти экрана?

1
ответ дан 1 December 2019 в 17:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: