- 主题:出乎意料,C++和dotnet6比dotnet5慢10% (转载)
C#都知道用引用,然后用C++写居然不用引用?
【 在 finlab 的大作中提到: 】
: 是的, 一般情况下, 这个范围的差异可以忽略。
: 这个测试比较单一。 不过可以推测,大家的浮点数运算也是接近的。
: 相同的运算基本生成相同的代码。
: ...................
--
FROM 114.245.195.*
超出机器字长的数据都要传引用/指针,不然就不要写C/C++然后怪C/C++慢了,哈哈
【 在 here080 的大作中提到: 】
: 这个是常用代码问题。
: 很多人写代码函数是直接“传值”。C#传值默认是传引用而C++是复制。
: C++确实需要对代码要求比较高才能达到想要的更好效果。
: ...................
--
FROM 114.245.195.*
我这里测试,c++比.net 5的慢一点点,
但是c++把那个new提出来之后,比.net 5的要快一点点。
但是c++再把那个new放回原位后,跟.net 5的差不多。
这里面有计时的问题,我用GetTickCount计时,这是受到tick精度影响的。
所以要首先把测量方法搞准。这个要不准的话,有个几百毫秒的差异都算是正常的。
13.x秒的三次是包括了new的,12.x秒的四次是提前new的(new的时间没算在内)。
c:\temp\test_LIEF\ConsoleApplication1\x64\Release>ConsoleApplication1.exe
time: 13.094
c:\temp\test_LIEF\ConsoleApplication1\x64\Release>ConsoleApplication1.exe
time: 13.250
c:\temp\test_LIEF\ConsoleApplication1\x64\Release>ConsoleApplication1.exe
time: 13.266
c:\temp\test_LIEF\ConsoleApplication1\x64\Release>ConsoleApplication1.exe
time: 12.593
c:\temp\test_LIEF\ConsoleApplication1\x64\Release>ConsoleApplication1.exe
time: 12.531
c:\temp\test_LIEF\ConsoleApplication1\x64\Release>ConsoleApplication1.exe
time: 12.672
c:\temp\test_LIEF\ConsoleApplication1\x64\Release>ConsoleApplication1.exe
time: 12.484
.net 5和.net 6都把new提到intperf()的外面。前三次是.net 5的,后几次是.net 6的
C:\temp\CsharpConsoleApp1\CsharpConsoleApp1>dotnet run CsharpConsoleApp1.dll
12.84
C:\temp\CsharpConsoleApp1\CsharpConsoleApp1>dotnet run CsharpConsoleApp1.dll
12.88
C:\temp\CsharpConsoleApp1\CsharpConsoleApp1>dotnet run CsharpConsoleApp1.dll
12.80
C:\temp\CsharpConsoleApp1\CsharpConsoleApp1>dotnet run CsharpConsoleApp1.dll
C:\Program Files\dotnet\sdk\6.0.100\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Sdk.DefaultItems.targets(134,5): warning NETSDK1182: 不支持在 Visual Studio 2019 中以 .NET 6.0 为目标。 [C:\temp\CsharpConsoleApp1\CsharpConsoleApp1\CsharpConsoleApp1.csproj]
12.98
C:\temp\CsharpConsoleApp1\CsharpConsoleApp1>dotnet run CsharpConsoleApp1.dll
C:\Program Files\dotnet\sdk\6.0.100\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Sdk.DefaultItems.targets(134,5): warning NETSDK1182: 不支持在 Visual Studio 2019 中以 .NET 6.0 为目标。 [C:\temp\CsharpConsoleApp1\CsharpConsoleApp1\CsharpConsoleApp1.csproj]
12.91
C:\temp\CsharpConsoleApp1\CsharpConsoleApp1>dotnet run CsharpConsoleApp1.dll
C:\Program Files\dotnet\sdk\6.0.100\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Sdk.DefaultItems.targets(134,5): warning NETSDK1182: 不支持在 Visual Studio 2019 中以 .NET 6.0 为目标。 [C:\temp\CsharpConsoleApp1\CsharpConsoleApp1\CsharpConsoleApp1.csproj]
12.75
C:\temp\CsharpConsoleApp1\CsharpConsoleApp1>dotnet run CsharpConsoleApp1.dll
C:\Program Files\dotnet\sdk\6.0.100\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Sdk.DefaultItems.targets(134,5): warning NETSDK1182: 不支持在 Visual Studio 2019 中以 .NET 6.0 为目标。 [C:\temp\CsharpConsoleApp1\CsharpConsoleApp1\CsharpConsoleApp1.csproj]
12.72
--
修改:z16166 FROM 114.245.195.*
FROM 114.245.195.*
c#、c++都把new提到intperf()的外面,又跑了一下,c++的略快那么一点点
这个new操作如果需要的内存大,很可能会走VirtualAlloc()进入内核态,也就是有开销。
c:\temp\test_LIEF\ConsoleApplication1\x64\Release>ConsoleApplication1.exe
time: 12.469 (GetTickCount64)
time: 12.473 (QueryPerformanceCounter)
c:\temp\test_LIEF\ConsoleApplication1\x64\Release>ConsoleApplication1.exe
time: 12.406 (GetTickCount64)
time: 12.395 (QueryPerformanceCounter)
c:\temp\test_LIEF\ConsoleApplication1\x64\Release>ConsoleApplication1.exe
time: 12.578 (GetTickCount64)
time: 12.574 (QueryPerformanceCounter)
c:\temp\test_LIEF\ConsoleApplication1\x64\Release>ConsoleApplication1.exe
time: 12.438 (GetTickCount64)
time: 12.446 (QueryPerformanceCounter)
c:\temp\test_LIEF\ConsoleApplication1\x64\Release>ConsoleApplication1.exe
time: 12.547 (GetTickCount64)
time: 12.541 (QueryPerformanceCounter)
c:\temp\test_LIEF\ConsoleApplication1\x64\Release>ConsoleApplication1.exe
time: 12.407 (GetTickCount64)
time: 12.409 (QueryPerformanceCounter)
//-------------------------------------------------------------------------
C:\temp\CsharpConsoleApp1\CsharpConsoleApp1>dotnet run CsharpConsoleApp1.dll
C:\Program Files\dotnet\sdk\6.0.100\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Sdk.DefaultItems.targets(134,5): warning NETSDK1182: 不支持在 Visual Studio 2019 中以 .NET 6.0 为目标。 [C:\temp\CsharpConsoleApp1\CsharpConsoleApp1\CsharpConsoleApp1.csproj]
12.953 (Environment.TickCount)
12.943 (QueryPerformanceCounter)
C:\temp\CsharpConsoleApp1\CsharpConsoleApp1>dotnet run CsharpConsoleApp1.dll
C:\Program Files\dotnet\sdk\6.0.100\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Sdk.DefaultItems.targets(134,5): warning NETSDK1182: 不支持在 Visual Studio 2019 中以 .NET 6.0 为目标。 [C:\temp\CsharpConsoleApp1\CsharpConsoleApp1\CsharpConsoleApp1.csproj]
12.844 (Environment.TickCount)
12.833 (QueryPerformanceCounter)
C:\temp\CsharpConsoleApp1\CsharpConsoleApp1>dotnet run CsharpConsoleApp1.dll
C:\Program Files\dotnet\sdk\6.0.100\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Sdk.DefaultItems.targets(134,5): warning NETSDK1182: 不支持在 Visual Studio 2019 中以 .NET 6.0 为目标。 [C:\temp\CsharpConsoleApp1\CsharpConsoleApp1\CsharpConsoleApp1.csproj]
12.813 (Environment.TickCount)
12.810 (QueryPerformanceCounter)
C:\temp\CsharpConsoleApp1\CsharpConsoleApp1>dotnet run CsharpConsoleApp1.dll
C:\Program Files\dotnet\sdk\6.0.100\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Sdk.DefaultItems.targets(134,5): warning NETSDK1182: 不支持在 Visual Studio 2019 中以 .NET 6.0 为目标。 [C:\temp\CsharpConsoleApp1\CsharpConsoleApp1\CsharpConsoleApp1.csproj]
12.843 (Environment.TickCount)
12.834 (QueryPerformanceCounter)
C:\temp\CsharpConsoleApp1\CsharpConsoleApp1>dotnet run CsharpConsoleApp1.dll
12.844 (Environment.TickCount)
12.851 (QueryPerformanceCounter)
C:\temp\CsharpConsoleApp1\CsharpConsoleApp1>dotnet run CsharpConsoleApp1.dll
12.766 (Environment.TickCount)
12.776 (QueryPerformanceCounter)
C:\temp\CsharpConsoleApp1\CsharpConsoleApp1>dotnet run CsharpConsoleApp1.dll
12.859 (Environment.TickCount)
12.850 (QueryPerformanceCounter)
C:\temp\CsharpConsoleApp1\CsharpConsoleApp1>dotnet run CsharpConsoleApp1.dll
12.781 (Environment.TickCount)
12.790 (QueryPerformanceCounter)
【 在 finlab 的大作中提到: 】
: 赞!
: 每次运行时间有波动,不过大体说明问题了
: C#基本运算并不慢,但是框架基础类开销相对大,一层层积累下来差异就体现出来了
: ...................
--
修改:z16166 FROM 114.245.195.*
FROM 114.245.195.*
我这里从12秒多降低到2秒,cpu是AMD 3700X
c:\temp\test_LIEF\ConsoleApplication1\x64\Release>ConsoleApplication1.exe
cc = 3001134
time: 2.093 (GetTickCount64)
time: 2.094 (QueryPerformanceCounter)
c:\temp\test_LIEF\ConsoleApplication1\x64\Release>ConsoleApplication1.exe
cc = 3001134
time: 2.094 (GetTickCount64)
time: 2.091 (QueryPerformanceCounter)
simd循环之后是可以continue跳过后面那个非simd的循环的
int intperf2() {
static const int zeroVector[8] = {0, 0, 0, 0, 0, 0, 0, 0};
static const int oneVector[8] = {1, 1, 1, 1, 1, 1, 1, 1};
__m256i zero = _mm256_loadu_si256((const __m256i *)zeroVector);
__m256i one = _mm256_loadu_si256((const __m256i *)oneVector);
int cc = 1;
buf[0] = 2;
for (int i = 3; i <= n; ++i) {
int flag = 1;
__m256i first = _mm256_setr_epi32(i, i, i, i, i, i, i, i);
int upperBound = cc & ~(8 - 1);
for (int it = 0; it < upperBound; it += 8) {
int j = buf[it];
if (j * j > i)
break;
__m256i second = _mm256_loadu_si256((const __m256i *)&buf[it]);
__m256i remainder = _mm256_rem_epi32(first, second);
if (_mm256_testz_si256(_mm256_cmpeq_epi32(remainder, zero), one) == 0) {
flag = 0;
break;
}
}
if (!flag)
continue;
for (int it = upperBound; it < cc; ++it) {
int j = buf[it];
if (j * j > i)
break;
if (i % j == 0) {
flag = 0;
break;
}
}
if (flag) {
buf[cc++] = i;
}
}
return cc;
}
【 在 finlab 的大作中提到: 】
: 我的cpu支持到avx2, 没有整数除法。但是Intel提供了svml,可以高效模拟除法和取模运算。
: 我试着用svml优化了C++,这次时间缩短到3.67秒。
: simd还是明显提高了速度。 不过估计整数除法是模拟的,提高远没有8倍那么多。
: ...................
--
修改:z16166 FROM 114.245.195.*
FROM 114.245.195.*
搜的:
jvm能自动搞点向量化,不过需要java码农写代码时配合,远不如jni自由。
jdk 16开始弄了一套跟上面C#的接口类似的东西
https://www.morling.dev/blog/fizzbuzz-simd-style/
https://openjdk.java.net/jeps/338
https://openjdk.java.net/jeps/414
【 在 hgoldfish 的大作中提到: 】
: 厉害!原来 c# 现在也能做 SIMD 优化了,而且写起来这么简单!c# 果然是现在最厉害的语言!只可惜是巨硬的。
: 不知道有没有人给个 java 的 SIMD 版本。
:
--
FROM 114.245.195.*