4

使用 fldcw 指令可以将 FPU 单元的精度更改为 24 位或更多位。然而,在做了一些测试之后,我开始认为实际上很少有 x87 操作使用该设置。

我尚未测试所有操作,但到目前为止,在这台测试机器上,看起来只有 fdiv 和 fsqrt 以选定的精度停止计算,并且所有其他操作(fadd fsub fmul ...)总是计算完整的扩展精度。

如果是这种情况,我希望它是因为这 2 条指令(fdiv 和 fsqrt)比大多数其他 x87 FPU 指令慢得多,所以当较低的精度足够时,可以加快它们的速度,但实际上,我只是想知道如果一直都是这种情况,或者这是我的测试机器中使用的最新处理器的怪癖。

编辑:这是显示它的delphi代码

program Project1;

uses
  windows,dialogs,sysutils;

{$R *.res}

const
 test_mul:single=1234567890.0987654321;

var
 i:longint;
 s:single absolute i;
 s1,s2,s3:single;

procedure test_24;
asm
 mov word([esp-2]),$103f  // 24bit precision, trunc
 fldcw word([esp-2])

 fld [s]
 fmul [test_mul]
 fstp [s1]
end;

procedure test_53;
asm
 mov word([esp-2]),$123f  // 53bit precision, trunc
 fldcw word([esp-2])

 fld [s]
 fmul [test_mul]
 fstp [s2]
end;

procedure test_64;
asm
 mov word([esp-2]),$133f  // 64bit precision, trunc
 fldcw word([esp-2])

 fld [s]
 fmul [test_mul]
 fstp [s3]
end;

begin
 i:=0;
 repeat
  test_24;
  test_53;
  test_64;

  if (s1<>s2) or (s2<>s3) then begin
   showmessage('Error at step:'+inttostr(i));
   break;
  end;

  inc(i);
 until i=0;
 showmessage('No difference found between precisions');
end.

edit2:误报,我弄错了,我存储为单个而不是扩展,所以无法发现差异,这是一个固定的测试,感谢 hans passant 发现了我的错误:

program Project1;

uses
  windows,dialogs,sysutils;

{$R *.res}

const
 test_mul:single=1234567890.0987654321;

var
 i:longint;
 errors:cardinal;
 s:single absolute i;
 s1,s2,s3:extended;

procedure test_24;
asm
 mov word([esp-2]),$103f  // 24bit precision, trunc
 fldcw word([esp-2])

 fld [s]
 fmul [test_mul]
 fstp [s1]
end;

procedure test_53;
asm
 mov word([esp-2]),$123f  // 53bit precision, trunc
 fldcw word([esp-2])

 fld [s]
 fmul [test_mul]
 fstp [s2]
end;

procedure test_64;
asm
 mov word([esp-2]),$133f  // 64bit precision, trunc
 fldcw word([esp-2])

 fld [s]
 fmul [test_mul]
 fstp [s3]
end;

begin
 errors:=0;
 i:=0;
 repeat
  test_24;
  test_53;
  test_64;

  if (s1<>s2) or (s2<>s3) then begin
   inc(errors);
  end;

  inc(i);
 until i=0;
 showmessage('Number of differences between precisions: '+inttostr(errors));
end.
4

0 回答 0