- 主题:出乎意料,C++和dotnet6比dotnet5慢10% (转载)
不用太认真,各种奇思妙想讨论下,尽管没啥用。
【 在 fanci 的大作中提到: 】
: 是的,惊呆了。
: 不会用赖语言,不过这可能是软件工程行业劣币驱逐良币的大趋势。
: - 来自 水木社区APP v3.5.3
--
FROM 27.223.78.*
局部变量全部放到外部做全局变量,循环变量改成register,用VC的release打开优化
【 在 finlab 的大作中提到: 】
: 代码还是发不出来。
:
: [upload=1][/upload]
--
FROM 106.3.194.*
编译优化的级别
【 在 finlab 的大作中提到: 】
: 发信人: finlab (挨踢卢瑟), 信区: Programming
: 标 题: 出乎意料,C++和dotnet6比dotnet5慢10%
: 发信站: 水木社区 (Sun Dec 12 11:19:41 2021), 站内
: ...................
--
FROM 221.221.50.*
还有数组访问方式,用下标比较慢,可考虑用指针遍历数组的方式 避免下标计算中的乘法。
【 在 finlab 的大作中提到: 】
: 发信人: finlab (挨踢卢瑟), 信区: Programming
: 标 题: 出乎意料,C++和dotnet6比dotnet5慢10%
: 发信站: 水木社区 (Sun Dec 12 11:19:41 2021), 站内
: ...................
--
FROM 221.221.50.*
我觉得是mingw的问题,还有你可以试试C的这个程序速度多少
--
FROM 106.120.203.*
C#也能手工循环展开啊。。。
--
FROM 1.91.33.*
我的cpu支持到avx2, 没有整数除法。但是Intel提供了svml,可以高效模拟除法和取模运算。
我试着用svml优化了C++,这次时间缩短到3.67秒。
simd还是明显提高了速度。 不过估计整数除法是模拟的,提高远没有8倍那么多。
int intperf3()
{
constexpr int n = 5000 * 10000;
int cc = 1;
int* buf = new int[n];
buf[0] = 2;
int vn = 8;
__m256i zero = _mm256_set_epi32(0, 0, 0, 0, 0, 0, 0, 0);
__m256i one = _mm256_set_epi32(1, 1, 1, 1, 1, 1, 1, 1);
__m256i vi, vj,vk;
for (int i = 3;i <= n;++i)
{
vi = _mm256_set_epi32(i, i, i, i, i, i, i, i);
int flag = 1;
int it = 0;
for (;it < cc-vn;it+=vn)
{
vj = _mm256_set_epi32(buf[it], buf[it + 1], buf[it + 2], buf[it + 3],
buf[it + 4], buf[it + 5], buf[it + 6], buf[it + 7]);
vk = _mm256_rem_epi32(vi, vj);
if (_mm256_testz_si256(_mm256_cmpeq_epi32(vk,zero),one)==0)
{
flag = 0;
break;
}
int j = buf[it];
if (j * j > i)
break;
}
for (;it < cc;++it)
{
int j = buf[it];
if (i % j == 0)
{
flag = 0;
break;
}
if (j * j > i)
break;
}
if (flag) { buf[cc++] = i; }
}
return cc;
}
【 在 leadu 的大作中提到: 】
: avx 等没有除法,优化不了,这个算法只能做partition然后靠cpu或gpu堆,写起来相当麻烦,一没留神就比不优化更慢
:
--
FROM 123.112.64.*
那个循环遍历不要从3开始逐一计算,从5开始的所有质数都是6n-1和6n+1的形式;所以循环可以从5开始,每个循环内部处理i和i+2,循环递增6即可
这样可以减少1/3的循环
【 在 finlab 的大作中提到: 】
: 我的cpu支持到avx2, 没有整数除法。但是Intel提供了svml,可以高效模拟除法和取模运算。
: 我试着用svml优化了C++,这次时间缩短到3.67秒。
: simd还是明显提高了速度。 不过估计整数除法是模拟的,提高远没有8倍那么多。
: ...................
--
FROM 221.218.209.*
我这里从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.*
这个是时间变成了1/2?
其实用不着太着急上硬件优化,一个程序可以优化的地方非常多,这也是为什么大家不再看重c++比c#快的那一点点的因素。
老鱼那个版本写的不好看,最后优化的也就万分之三。这不是一个有意义的优化度。
即使上硬件优化的话也最好一次到位,gpu或fpga的,中间的太尴尬
给你个新算法,时间是你原版的1/8的样子。而且还可以进一步做并行优化。只是我懒得搞了,c#版本不做任何优化已经够快了。
| Method | Mean | Error | StdDev | Ratio |
|---------- |-----------:|--------:|---------:|------:|
| intperf | 3,478.1 ms | 0.46 ms | 0.39 ms | 1.00 |
| | | | | |
| intperf3 | 652.8 ms | 6.36 ms | 5.63 ms | 1.00 |
| | | | | |
| intperf32 | 466.2 ms | 9.17 ms | 16.76 ms | 1.00 |
// * Legends *
Mean : Arithmetic mean of all measurements
Error : Half of 99.9% confidence interval
StdDev : Standard deviation of all measurements
Ratio : Mean of the ratio distribution ([Current]/[Baseline])
1 ms : 1 Millisecond (0.001 sec)
[Benchmark]
public int intperf3()
{
var notprime = new byte[n];
notprime[0] = 1;
notprime[1] = 1;
var t = n / 2;
for (int i = 2; i <= t; i++)
{
if (notprime[i]==0)
{
for (int j = i + i; j < n; j += i)
{
notprime[j] = 1;
}
}
}
return n-notprime.Sum(x=>x);
}
[Benchmark]
public void intperf32()
{
var notprime = new byte[n];
notprime[0] = 1;
notprime[1] = 1;
var t = n / 2;
for (int i = 2; i <= t; i++)
{
if (notprime[i] == 0)
{
for (int j = i + i; j < n; j += i)
{
notprime[j] = 1;
}
}
}
}
【 在 finlab 的大作中提到: 】
: 我的cpu支持到avx2, 没有整数除法。但是Intel提供了svml,可以高效模拟除法和取模运算。
: 我试着用svml优化了C++,这次时间缩短到3.67秒。
: simd还是明显提高了速度。 不过估计整数除法是模拟的,提高远没有8倍那么多。
: ...................
--
修改:leadu FROM 123.116.198.*
FROM 123.116.198.*