- 主题:出乎意料,C++和dotnet6比dotnet5慢10% (转载)
有些 micro benchmark 还会发现 python 比 cpp 快呢。
在 programming 版看到你发的代码了。直觉你的 cpp 代码还可以进行改进。比如减少在循环里面的两个 if() 判断,那个太伤 cpu 的流水线了。
而 c# 代码想要进一步的改进可能比较难。
所以结论是,并不是 cpp 写计算代码一定更快,但是 cpp 的优化上限和汇编差不多。天花板很高。
【 在 finlab (挨踢卢瑟) 的大作中提到: 】
: 用vc++2022版测试, 6.55秒, 还是明显比c#慢。
--
修改:hgoldfish FROM 124.72.118.*
FROM 124.72.118.*
c# 和 java 的计算代码本来就不慢。java 还需要 jit 预热,c# 在编译的时候听说可以直接编译到 native
或许你再试试,c# 里不用 int[] 而是 vector<> ,并且改成从外部传进来。对于稍复杂的对象,c# 这种虚拟机语言存取内存的低效就能看出来了。
如果是 io 代码,更容易看出虚拟机语言的问题。一是虚拟机语言的序列化低效,二是虚拟机语言占用的内存偏多。所以用 cpp/go 写后端服务器,正常都会比 java/c# 快且省内存。
【 在 finlab (挨踢卢瑟) 的大作中提到: 】
: 我比的就是正常代码, 不用专门优化情况下的性能。
: 同样的逻辑, 不管什么原因。 如果人家C#编译器能优化,C++编译器就优化不了,那就是C#的优势。
--
修改:hgoldfish FROM 124.72.118.*
FROM 124.72.118.*
List<int> buf = new List<int>();
buf.Add(2);
不是有 n 个元素吗?
【 在 finlab (挨踢卢瑟) 的大作中提到: 】
: 修改了c#的代码,还是dotnet5.0 , 使用了C#提供的容器和linq。 速度更快了一点
: 5.81秒就完成了。
: dotnet 6 还是要6.6秒。
: ...................
--
FROM 124.72.118.*
随便写的代码,cpp 还经常弱于 python 和 c# 呢。c# 和 python 底层用的都是优化过的 c 代码。
我觉得 cpp 写代码的好处在于优化上限高,内存占用低。我优化一下这段代码看看。。
【 在 finlab (挨踢卢瑟) 的大作中提到: 】
: 高品质的C++代码肯定比C#快。
: 但是我想了解的是普通人写的,没有高度优化的“正常”代码。
: 这种情况下对大多数人才有意义。
: ...................
--
修改:hgoldfish FROM 124.72.118.*
FROM 124.72.118.*
下面这段代码试了一下,可以优化 20% 左右。
#include <vector>
#include <cmath>
#include <iostream>
using namespace std;
int intperf()
{
constexpr int n = 5000 * 10000;
bool found = false;
vector<int> primes;
primes.reserve(n);
primes.push_back(2);
primes.push_back(2);
primes.push_back(2);
primes.push_back(2);
for (int i = 3; i <= n; i += 2) {
int t = static_cast<int>(primes.size()) - 4;
for (int it = 0; it <= t ; it += 4) {
int j0 = primes[it + 0];
int j1 = primes[it + 1];
int j2 = primes[it + 2];
int j3 = primes[it + 3];
if ((i % j0 == 0) || (i % j1 == 0) || (i % j2 == 0) || (i % j3 == 0)) {
found = true;
break;
}
if (j0 * j0 > i) {
break;
}
}
if (!found) {
primes[t + 1] = i;
primes.push_back(2);
} else {
found = false;
}
}
return primes.size() - 3;
}
int main()
{
cout << intperf() << endl;
return 0;
}
【 在 hgoldfish (老鱼) 的大作中提到: 】
: 随便写的代码,cpp 还经常弱于 python 和 c# 呢。c# 和 python 底层用的都是优化过的 c 代码。
: 我觉得 cpp 写代码的好处在于优化上限高,内存占用低。我优化一下这段代码看看。。
--
修改:hgoldfish FROM 124.72.118.*
FROM 124.72.118.*
对。。我猜会稍微快一点的原因是一次性加载四个 int 到四个寄存器里面,能把流水线填得满一点?
如果 int % 操作能够用 avx 指令并行化的话,速度是不是可以更快一些?可惜我不太懂得这个怎么用 avx SIMD 并行化。
【 在 Bernstein (Berns) 的大作中提到: 】
: 手工循环展开
--
FROM 124.72.118.*
有除法的啊。但没有求 mod 的。
mm256_div_pd
【 在 leadu (leadu) 的大作中提到: 】
: avx 等没有除法,优化不了,这个算法只能做partition然后靠cpu或gpu堆,写起来相当麻烦,一没留神就比不优化更慢
--
FROM 124.72.118.*
里面有很多时候是测试了一两个素数就跳出循环了。用开方说不定速度更慢。
本质上是这个素数算法比较低效。不过是这个算法是很好的例子,解释 c#, java 这些 jit 语言和 c++ 的区别。c++ 对同一个算法,可以无限优化跟手动汇编差不多快,c#/java 不好搞。但 c#/java 随便撸都能有一个还不错的结果,至少不会访问内存崩溃掉。
【 在 here080 (hero080) 的大作中提到: 】
: 乘法那个是另一个问题。
: 完全可以在内循环之外先开方。
--
FROM 124.72.118.*
厉害!原来 c# 现在也能做 SIMD 优化了,而且写起来这么简单!c# 果然是现在最厉害的语言!只可惜是巨硬的。
不知道有没有人给个 java 的 SIMD 版本。
【 在 finlab (挨踢卢瑟) 的大作中提到: 】
: 今天晚上重新实现了C#的simd, 在我的i5 8265U上只需要1.8秒了,比simd 的C++的2.96秒还快很多。
: 需要说明的是,昨天直接用AVX2指令实现simd, 因为不支持除法,先把int转成float然后做除法。
: 结果一直不对,发现是对于比较大的i,转成float后精度损失了,所以结果就不对了。
: ...................
--
FROM 124.72.118.*