На 64-битной JVM чтение и запись двойного атомарного? - PullRequest
1 голос
/ 09 октября 2019

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

Итак, я написал простой тест и нашелудвоения были обычно быстрее (на волосок), и единственное время, когда я заметил большую разницу, было, когда у меня была ошибка в коде, и я конвертировал назад и вперед между double и float (сохраненный как 3-й контрольный пример). Когда математика была чисто двойной или чистой плавающей точкой, тесты были почти такими же. (Java 1.8, 64-битная Oracle JVM)

Однако я читал, что двойные и длинные операции чтения и записи не являются атомарными, а рассматриваются как 32-битные операции чтения и записи в JVM.

Не должноЯ ожидаю разницу в производительности?
public class Benchmark
{
   static double loopDouble (double aAddValue)
   {
      double tResult = 0.0;
      while (tResult < 10000000.0)
      {
         tResult += aAddValue;
      }

      return tResult;
   }

   static double loopFloat (float aAddValue)
   {
      double tResult = 0.0;
      while (tResult < 10000000.0)
      {
         tResult += aAddValue;
      }

      return tResult;
   }

   static float loopFloatFloat (float aAddValue)
   {
      float tResult = 0.0f;
      while (tResult < 10000000.0f)
      {
         tResult += aAddValue;
      }

      return tResult;
   }

   static double loopInt (int aAddValue)
   {
      double tResult = 0.0;
      while (tResult < 10000000.0)
      {
         tResult += aAddValue;
      }

      return tResult;
   }

   public static void main(String[] args)
   {

      long doubleTimeNs = - System.nanoTime();
      loopDouble(1.0);
      doubleTimeNs += System.nanoTime();

      long floatTimeNs = - System.nanoTime();
      loopFloat(1.0f);
      floatTimeNs += System.nanoTime();

      long floatfloatTimeNs = - System.nanoTime();
      loopFloatFloat(1.0f);
      floatfloatTimeNs += System.nanoTime();

      long intTimeNs = -System.nanoTime();
      loopInt(1);
      intTimeNs += System.nanoTime();

      long doubleTime2Ns = - System.nanoTime();
      loopDouble(1.0);
      doubleTime2Ns += System.nanoTime();

      System.out.println("Double: " + doubleTimeNs + " (" + doubleTime2Ns + ") "+ " Float: " + floatTimeNs + " Float-float: " + floatfloatTimeNs +  " Int: " + intTimeNs);
   }
}



Double: 23944257 (23736683)  Float: 24220307 Float-float: 24134056 Int: 25745599

1 Ответ

0 голосов
/ 10 октября 2019

Указано Келли Денехи. JLS секция 17.7

"Для целей модели памяти языка программирования Java одна запись в энергонезависимое длинное или двойное значение рассматривается как две отдельные записи: одна на каждую 32-битную половинуЭто может привести к ситуации, когда поток видит первые 32 бита 64-битного значения из одной записи, а вторые 32 бита из другой записи.

Записывает и считывает изменяемые длинные и двойные значения. всегда атомарный.

Запись и чтение ссылок всегда атомарны, независимо от того, реализованы ли они как 32-битные или 64-битные значения. "

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...