что не так с синусами?

В IL коде + компилируется в IL оператор add, и для real, и для single, и для integer.
А в коде процессора - я так понимаю, будет зависеть от процессора. Но точно можно сказать 2 вещи:

  1. single это не дубль real:
begin
  sizeof(single).Println;
  sizeof(real).Println;
end.
  1. Конвертация из single в real и назад - вряд ли выполняется для каждой операции, иначе времени надо было бы на много больше.

Поэтому, мне кажется, single не эмулируют, вместо этого все нормальные процессоры - просто поддерживают его так же как real. Ну и это логично, ибо большинство C++ программистов всё ещё свой float для всего используют.

Это понятно, надо быть не знаю кем, чтобы заложить в компилятор на каждой операции конвертацию “туда-назад”. Скорее всего, сейчас single приводится к real, выполняются операции, а затем результат приводится к single. В вот в том же “чистом” С есть реализация математики отдельно для single и double, вот где и надо пробовать.

single:
  + : 00:00:08.5588211
  - : 00:00:11.0706888
  * : 00:00:08.7122414
  / : 00:00:08.7445548

real:
  + : 00:00:08.6658372
  - : 00:00:08.6070968
  * : 00:00:08.6511752
  / : 00:00:08.6753983

Прикольно, что такой МИНУС в производительности вычитания именно на AMD процессорах))

Ну вообще то… При сложении 2 чисел типа byte происходит конвертация обоих в integer, и затем конвертация результата в byte, и так с каждым числовым типом меньше integer, в каждой мат. операции… Но, конечно, тут это не так криминально, ибо в отличии от single и real - конвертация целых чисел, это добавление ноликов или обрезание того что не помещается.

Попробуйте это…

begin
  var k := 10000000;
  var (a1, b1, c1, d1) :=
      (real(3e-4), real(18), real(352.53234), real(0.043));
  var (a2, c2) :=
      (single(3e-4), single(352.53234));
  var q1: real;
  var q2: single;
  var t: integer;
  loop 5 do
  begin
    Milliseconds;
    for var i := 1 to k do
      q1 := a1 * ln(b1) + sin(c1) / d1 ** 0.18;
    t := MillisecondsDelta;
    t.Print;
    Milliseconds;
    for var i := 1 to k do
      q2 := a2 * ln(b1) + sin(c2) / d1 ** 0.18;
    t := MillisecondsDelta;
    t.Println
  end
end.
139 138
137 138
143 139
139 138
137 139
1612 1630 
1600 1630 
1612 1706 
1602 1656 
1610 1632 

А, я понял, это оболочка виновата и отладчик… Занятно, что они тормозят скорость на порядок. Похоже, что .NET нивелирует разницу в использовании вещественных данных различных типов, приводя их к единому.

Насчёт преимуществ скорости на х32 не уверен, а вот двойная экономия выглядит привлекательно и без ущерба требуемой точности.

Двойная экономия чего? Памяти? На массиве, содержащем миллион элементов типа single Вы сэкономите 4 мегабайта. На фоне объема памяти современных компьютеров это менее 1%. А все константы тоже будете явно приводить к single? Насчет требуемой точности - это смотря какого рода задачи Вы решаете. Например, в численных методах использование single “смерти подобно” из-за катастрофического накопления ошибок представления чисел.

1 лайк