Быстрый прямой порядок байтов к преобразованию с обратным порядком байтов в ASM

Мне нравится , объяснение Jenkov

синхронизировалось

, Синхронизируемые блоки в Java отмечены с synchronized ключевое слово. Синхронизируемый блок в Java синхронизируется на некотором объекте. Все синхронизируемые блоки, синхронизируемые на том же объекте, могут только иметь одно выполнение потока в них одновременно. Все другие потоки, пытающиеся ввести синхронизируемый блок, заблокированы, пока поток в синхронизируемом блоке не выходит из блока.

происходит - прежде [О] , глоток>

разблокировать (синхронизировал блок, или выход метода) монитора happens-before каждая последующая блокировка (синхронизировал блок или запись метода) того же самого монитора.

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

От Java 5

Java Concurrency Utilities

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

5
задан starblue 17 October 2009 в 19:49
поделиться

3 ответа

Для большого объема данных инструкция bswap (доступна в Visual C ++ в рамках _byteswap_ushort , _byteswap_ulong и _byteswap_uint64 intrinsics) - это правильный путь. Это даже превосходит рукописную сборку. Они недоступны в чистом C # без P / Invoke, поэтому:

  1. Используйте это, только если у вас есть много данных для обмена байтами.
  2. Вам следует серьезно подумать о написании приложения самого низкого уровня. / O в управляемом C ++, чтобы вы могли выполнить замену, прежде чем переносить данные в управляемый массив. Вам уже нужно написать библиотеку C ++, поэтому терять особо нечего, и вы обойдете все проблемы производительности, связанные с P / Invoke, для алгоритмов низкой сложности, работающих с большими наборами данных.

PS: Многие люди не знают о встроенных функциях подкачки байтов. Их производительность поразительна, вдвойне лучше для данных с плавающей запятой, потому что они обрабатываются как целые числа. Невозможно победить его без ручного кодирования загрузки вашего регистра для каждого отдельного варианта использования подкачки байтов, и если вы попробуете это, вы, вероятно, получите больший удар в оптимизаторе, чем когда-либо.

7
ответ дан 13 December 2019 в 22:12
поделиться

Я думал рассмотреть два uint types как тип ulong

Ну, это также поменяет местами два значения uint, что может быть нежелательно ...

Вы можете попробовать какой-нибудь код C # в небезопасном режиме, который на самом деле может работать достаточно хорошо. Например:

public static unsafe void SwapInts(uint[] data) {
   int cnt = data.Length;
   fixed (uint* d = data) {
      byte* p = (byte*)d;
      while (cnt-- > 0) {
         byte a = *p;
         p++;
         byte b = *p;
         *p = *(p + 1);
         p++;
         *p = b;
         p++;
         *(p - 3) = *p;
         *p = a;
         p++;
      }
   }
}

На моем компьютере пропускная способность составляет около 2 ГБ в секунду.

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

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

LDLOC 0
SHL 24
LDLOC 0
LDC.i4 0x0000ff00
SHL 8
OR
LDLOC 0
LDC.i4 0x00ff0000
SHL.UN 8
OR
LDLOC 0
SHL.UN 24
OR

Максимум 13 (x86) ассемблерных инструкций на число (и, скорее всего, интерпретатор будет еще умнее, если будет использовать умные регистры). И это не может быть более наивным, чем это.

Теперь сравните это со стоимостью

  • загрузки данных (включая любые периферийные устройства, с которыми вы работаете!)
  • Манипуляция данными (выполнение сравнений , например)
  • Вывод результата (каким бы он ни был)

Если 13 инструкций на число составляют значительную часть времени выполнения, то вы выполняете ОЧЕНЬ высокопроизводительную задачу и должны иметь ввод в правильном формате ! Вы также, вероятно, не будете использовать управляемый язык, потому что вам нужен гораздо больший контроль над буферами данных и чем-то еще, и без дополнительной проверки границ массива.

2
ответ дан 13 December 2019 в 22:12
поделиться
Другие вопросы по тегам:

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