我发现C anc C#中类似代码之间存在巨大的性能差异.
C代码是:
#include <stdio.h>
#include <time.h>
#include <math.h>
main()
{
int i;
double root;
clock_t start = clock();
for (i = 0 ; i <= 100000000; i++){
root = sqrt(i);
}
printf("Time elapsed: %f\n", ((double)clock() - start) / CLOCKS_PER_SEC);
}
Run Code Online (Sandbox Code Playgroud)
而C#(控制台应用程序)是:
using System;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
DateTime startTime = DateTime.Now;
double root;
for (int i = 0; i <= 100000000; i++)
{
root = Math.Sqrt(i);
} …
Run Code Online (Sandbox Code Playgroud) 这个问题可能听起来像初学者,但是当我发现这个问题时,我认为我要么是初学者,要么我的作品缺少一些东西:
int main()
{
cout << sizeof(double) << endl;
cout << sizeof(long double) << endl;
cout << DBL_DIG << endl;
cout << LDBL_DIG << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
计划产出:
8
8
15
15
我认为long double
是10个字节,有18个十进制数字,而double
8个字节,有15个数字,但似乎我错了.
为什么会这样?
在64位机器上使用MSVC 2010.
在查看x86/x64架构中的寄存器表之后,我注意到有128,256和512位寄存器的整个部分,我从未见过它们用于汇编或反编译的C/C++代码: XMM(0-15)表示128,YMM(0-15)表示256,ZMM(0-31)512.
做了一些挖后我所收集的是,你必须使用2个64位操作,以一个128位的数字进行的,而不是使用通用的数学,add
,sub
,mul
,div
操作.如果是这种情况,那么具有这些扩展寄存器集的用途究竟是什么,是否有任何汇编操作可以用来操作它们?
具体来说,我谈论的是x87 PC架构和C编译器。
我正在编写自己的解释器,double
数据类型背后的推理使我感到困惑。特别是在效率方面。有人可以解释为什么C选择了64位double
而不是硬件本机80位double
吗?又为什么硬件没有设置在80位double
上呢?每种性能都有什么影响?我想使用80位double
作为默认数字类型。但是编译器开发人员的选择让我担心这不是最佳选择。
double
在x86上仅短2个字节,为什么编译器long double
默认不使用10个字节?long double
vs所带来的额外精度的例子double
吗?long double
默认情况下禁用它?long double
典型的x86 / x64 PC硬件的差/慢多少?考虑以下代码:
\n#include <iostream>\n\nusing namespace std;\n\nint main(int argc, char *argv[])\n{\n long double test = 0xFFFFFFFFFFFFFFFF;\n cout << "1: " << test << endl;\n unsigned long long test2 = test;\n cout << "2: " << test2 << endl;\n cout << "3: " << (unsigned long long)test << endl;\n return 0;\n}\n
Run Code Online (Sandbox Code Playgroud)\n使用 GCC g++ (7.5.0) 编译此代码并运行会产生预期的以下输出:
\n1: 1.84467e+19\n2: 18446744073709551615\n3: 18446744073709551615\n
Run Code Online (Sandbox Code Playgroud)\n但是,使用 Microsoft Visual C++ 编译器(16.8.31019.35,64 位和 32 位)对其进行编译并运行会产生以下输出:
\n1: 1.84467e+19\n2: 9223372036854775808\n3: 9223372036854775808\n
Run Code Online (Sandbox Code Playgroud)\n将值转换为 an 时unsigned long …
使用 Visual Studio Community 2019 v16.4.2 和它在 64 位 Win10 上附带的最新内容。
在测试各种数据类型限制时遇到了一个奇怪的错误,numeric_limits 无法区分 double 和 long double 最小/最大值。使用带有默认 GNU Mac 工具链的 NetBeans 显示更合理的结果。
// Type limits: float
std::cout
<< "MIN float " << numeric_limits<float>::min() << "\n"
<< "MAX float " << numeric_limits<float>::max() << "\n"
<< "MIN double " << numeric_limits<double>::min() << "\n"
<< "MAX double " << numeric_limits<double>::max() << "\n"
<< "MIN long double " << numeric_limits<long double>::min() << "\n"
<< "MAX long double " << numeric_limits<long double>::max() << "\n"; …
Run Code Online (Sandbox Code Playgroud) 我知道这似乎是一个太简单的问题,但我很难理解double
&的含义/含义long
。所有在线资源均给出官方定义。我正在寻找外行的解释。
简而言之,我的问题是: a long long
、 along double
和 a之间有什么区别long float
?
我尝试运行快速测试(附有屏幕截图)以查看每种类型的字节大小,但无法理解它。a 的大小如何long double
与 a 相同double
?
c++ ×3
long-double ×3
c ×2
double ×2
performance ×2
visual-c++ ×2
assembly ×1
c# ×1
casting ×1
precision ×1
simd ×1
sse ×1
x86 ×1
x86-64 ×1