导航:
论坛 -> DELPHI技术
斑竹:liumazi,sephil
作者:
hectic (村雨Hectic)
▲▲▲▲▲
-
普通会员
2023/8/21 0:12:54
标题:
[b]Delphi在64位编译下的UInt64的严重性能问题,我没找到原因[/b]
浏览:1415
加入我的收藏
楼主:
因为看到一个国外的帖子 https://en.delphipraxis.net/topic/6522-strange-benchmark-results-am-i-missing-something/ 作者用int64循环对比了delphi11.3和pypy3.9,delphi居然慢了近三倍,作为本地编译语言我怀疑作者造假,所以自己试了下,对比lazarus2.2.6和qtc++vc2022和golang1.21和dotnet7,结果让我不敢相信,我觉得delphi这里大概率有设计问题,但是找不到原因 机器 rog冰刃4 i7 10875h 32G 系统 win11 专业版 下面的所有测试exe都是64位release编译,并且单独在控制台窗口执行,并不是从ide启动。计时所有语言都用的GetTickCount64这个API。但是我觉得这个差距已经跟计时方法没什么关系了。 先发delphi11.3的,三次都是耗时9秒多
此帖子包含附件: 大小: 96.4K
----------------------------------------------
-
作者:
hectic (村雨Hectic)
▲▲▲▲▲
-
普通会员
2023/8/21 0:13:30
1楼:
这是lazarus2.2.6
此帖子包含附件: 大小: 139.4K
----------------------------------------------
-
作者:
hectic (村雨Hectic)
▲▲▲▲▲
-
普通会员
2023/8/21 0:15:19
2楼:
这是qtcreator用的vc2022编译器编译的,我觉得bcb应该没必要测试,不会比vc慢的,我很想用bcb,但是谁有delphi和bcb社区版共存的安装方法?
此帖子包含附件: 大小: 103.5K
----------------------------------------------
-
作者:
hectic (村雨Hectic)
▲▲▲▲▲
-
普通会员
2023/8/21 0:15:46
3楼:
这是golang1.21
此帖子包含附件: 大小: 95.4K
----------------------------------------------
-
作者:
hectic (村雨Hectic)
▲▲▲▲▲
-
普通会员
2023/8/21 0:16:16
4楼:
这是dotnet7
此帖子包含附件: 大小: 127.2K
----------------------------------------------
-
作者:
hectic (村雨Hectic)
▲▲▲▲▲
-
普通会员
2023/8/21 0:16:47
5楼:
这是dotnet7的native aot
此帖子包含附件: 大小: 75.1K
----------------------------------------------
-
作者:
hectic (村雨Hectic)
▲▲▲▲▲
-
普通会员
2023/8/21 0:18:05
6楼:
nodejs没测试结果,因为js本身不支持uint64,得借助第三方的bitint来实现,那个速度我觉得没必要浪费电了。
----------------------------------------------
-
作者:
hectic (村雨Hectic)
▲▲▲▲▲
-
普通会员
2023/8/21 1:20:19
7楼:
突然想起来还有rust,我用的1,73 nightly版本
此帖子包含附件: 大小: 103.1K
----------------------------------------------
-
作者:
2023/8/21 8:16:55
8楼:
hectic (村雨Hectic) 我试了,xe11.3在我的机上要11秒多,但用的D12只要2秒,D12的64位取余做了些优化,可以对比一下汇编
----------------------------------------------
-
作者:
2023/8/21 8:33:08
9楼:
vs rust 的部分, 其實, DELPHI, FPC, VC, GCC 等,都可以開-O3 看看。 這種簡單的, 不用擔心-O3 會玩壞你的APP。 FPC 測, 有沒有開 -O3 差300ms 左右
----------------------------------------------
-
作者:
2023/8/21 8:39:23
10楼:
delphi的32位虽然落后,还可以一战. 64位本来就没怎么作优化. 不慢才是出鬼了.
----------------------------------------------
-
作者:
yookee (yookee)
★☆☆☆☆
-
盒子活跃会员
2023/8/21 9:10:31
10楼:
虽说主要的锅可能是要Delphi来背,但是操作系统和硬件的配合也要承担一定责任。 笔记本的电源模式也会有影响。 5600X Win11 D11.3
此帖子包含附件: 大小: 70.9K
----------------------------------------------
-
作者:
2023/8/21 9:12:21
11楼:
我试了 vs 2013, .net 4.8,也要10秒,并没有快
----------------------------------------------
-
作者:
2023/8/21 9:13:18
12楼:
yookee (yookee)下一个D12,要快很多
----------------------------------------------
-
作者:
2023/8/21 9:42:21
13楼:
我的电脑,jdk 1.8要2.2秒,jdk 20是1.4秒, 但D12只要2秒
----------------------------------------------
-
作者:
hectic (村雨Hectic)
▲▲▲▲▲
-
普通会员
2023/8/21 10:08:06
14楼:
to powerpcer: lazarus 2.2.6 debug模式无优化 1859ms 开不开o3的确有区别,哪怕o2也有区别,但是11.3这个差距太大了,不是o3能解决的,目前看来测试版12.0解决了这个问题
此帖子包含附件: 大小: 131.9K
----------------------------------------------
-
作者:
hectic (村雨Hectic)
▲▲▲▲▲
-
普通会员
2023/8/21 10:11:52
15楼:
to yookee: 现在不是机器性能的问题,是同一台机器同一个环境下11.3的差距太大了,肯定是delphi本身的问题,如果在你机器上11.3只要3秒的话,那你试试c++ lazaruz rust可能在500毫秒内就跑完了 我喜欢delphi,我并不在意delphi跑这个循环要花费9秒,我在意的是为什么在uint64上它和别的语言差距这么悬殊,如果同硬件测试环境下lazarus golang c++ dotnet rust它们和delphi花费的时间差不多,那没问题。
----------------------------------------------
-
作者:
hectic (村雨Hectic)
▲▲▲▲▲
-
普通会员
2023/8/21 10:19:32
16楼:
to hq200306: 你的测试方式是release64吗? 我这里net4.8.1 64位release比dotnet7和qtc++都快,几乎和rust一样
此帖子包含附件: 大小: 130.1K
----------------------------------------------
-
作者:
hectic (村雨Hectic)
▲▲▲▲▲
-
普通会员
2023/8/21 10:27:22
17楼:
朋友们,不要对比机器性能,我所有测试都是同一台机器同一个系统下一起测的,rog冰刃4本来就是几年前的配置,你找一台13代i9或最新的amd肯定能跑的比我快很多,但是没有意义,因为如果delphi11.3在你的机器上能比我机器快好几倍,那lazarus c++ rust dotnet golang一样也会快这个倍数,11.3和他们差距依然存在。你应该在你这台机器上同时测11.3 lazarus c++ golang dotnet7 rust,如果证明他们差距不大,那才有意义。 我并不介意delphi的uint64循环它自己要跑多久,只是同硬件同环境下和别的语言的差距不应该这么大,如果大家都一样速度,哪怕要跑一小时,也无所谓。
----------------------------------------------
-
作者:
hectic (村雨Hectic)
▲▲▲▲▲
-
普通会员
2023/8/21 11:00:24
19楼:
to bdl1: 你的11.3最后计算结果是233333334166666668吗?居然比12都快,怎么设置的? 我把uint64改成CppULongInt只用了2984ms,但是CppULongInt装不下这个大数,计算结果不对。
此帖子包含附件: 大小: 67.3K
----------------------------------------------
-
作者:
2023/8/21 11:02:05
19楼:
Intel Core I3-4160 CPU @3.6GHZ, Win10 22H2 64Bit [更正] Delphi 10.3 64bit: 11.6秒 Delphi 10.3 32bit: 9.9秒 Julia 1.72 64bit: 2.8秒
----------------------------------------------
-
作者:
bdl1 (bdl1)
▲▲▲▲▲
-
普通会员
2023/8/21 11:02:40
18楼:
d11.3:1874 d12:1092 win64 release
----------------------------------------------
-我的博客
作者:
hectic (村雨Hectic)
▲▲▲▲▲
-
普通会员
2023/8/21 11:02:47
20楼:
朋友们注意下 计算结果应该是233333334166666668,只有UInt64能装下,其他CppULongInt Int64 ULong都不行,而且循环次数是10亿不是1亿,1后面9个零
----------------------------------------------
-
作者:
hectic (村雨Hectic)
▲▲▲▲▲
-
普通会员
2023/8/21 11:06:12
21楼:
to bdl1: 你的11.3比12都快?怎么设置的? 我是了换成别的类型比如CppULongInt可以3秒,但是计算结果不对, 装不下233333334166666668这个大数。
----------------------------------------------
-
作者:
2023/8/21 11:08:29
22楼:
@hectic (村雨Hectic),离开vs2013,只花1.5秒,在vs2013环境执行要10秒
----------------------------------------------
-
作者:
2023/8/21 11:09:57
23楼:
这个测试代码,只是cpu的整除指令慢
----------------------------------------------
-
作者:
hectic (村雨Hectic)
▲▲▲▲▲
-
普通会员
2023/8/21 11:11:40
22楼:
11.3换成32位release编译,同硬件测试环境 只要5.7秒,比64位release编译出来的9秒多快了近一倍 看来delphi64位编译器本身也有问题
此帖子包含附件: 大小: 72.1K
----------------------------------------------
-
作者:
hectic (村雨Hectic)
▲▲▲▲▲
-
普通会员
2023/8/21 11:14:31
24楼:
to hq200306: 那是肯定,你带ide启动会带进去大量的插桩给断点和变量快照用,我所有测试都是默认64位release编译完,然后单独开一个控制台去跑。
----------------------------------------------
-
作者:
2023/8/21 11:15:55
25楼:
hectic (村雨Hectic)装个D12测试来测试,会快很多
----------------------------------------------
-
作者:
hectic (村雨Hectic)
▲▲▲▲▲
-
普通会员
2023/8/21 11:20:21
26楼:
to hq200306: 现在12刚出来还是测试版,测试版有key吗?不是正版用户安装不了吧? 以前delphi我都用的和谐版,10开始我都用社区版了。
----------------------------------------------
-
作者:
hectic (村雨Hectic)
▲▲▲▲▲
-
普通会员
2023/8/21 11:26:27
28楼:
to hq200306: 谢谢老板,我去下个试试。
----------------------------------------------
-
作者:
2023/8/21 11:27:19
29楼:
就汇编的div慢
----------------------------------------------
-
作者:
2023/8/21 13:31:02
30楼:
mod 要用到div / idiv
----------------------------------------------
-
作者:
tuao (tuao)
★☆☆☆☆
-
盒子活跃会员
2023/8/21 14:28:16
31楼:
不知有没有替代div mod的汇编函数
----------------------------------------------
tuao
作者:
szlbz (秋风)
★☆☆☆☆
-
盒子活跃会员
2023/8/21 14:36:00
31楼:
刚用lazarus测了一下不同CPU架构的速度: 1、lazarus 2.26,fpc 3.2.2,win10,i5-8279U CPU @ 2.40GHz :1469ms 2、lazarus 2.26,fpc 3.2.2,银河麒麟 V10 SP1,华为麒麟990:7161ms 3、lazarus 2.3,fpc 3.3.1,UOS 1060,龙芯3A5000 2.5GHz:7528ms
----------------------------------------------
-
作者:
2023/8/21 15:38:34
32楼:
to hectic: 很久以前,多数语言的编译器产生的机器码中,对除数为立即数的整数除法 a / b ,都已经优化成 a * (2^n / b) 再右移n位了(其中(2^n / b)在编译时求出来,另外有的b可能需要做些舍入调整,不过大致是这个原理),因为 mul/imul机器指令比div/idiv要快得多。而Delphi的编译器至今还不能对除数为立即数的整数除法做这种优化,只能编译为慢吞吞的div/idiv指令。整数取余同理
----------------------------------------------
-
作者:
hectic (村雨Hectic)
▲▲▲▲▲
-
普通会员
2023/8/21 15:53:28
33楼:
我把delphi11.3社区版卸载了,换了bcb11.3社区版测试了 下 同上面的硬件环境 64 release,不出所料和qtc++64的速度一样
此帖子包含附件: 大小: 72.4K
----------------------------------------------
-
作者:
hectic (村雨Hectic)
▲▲▲▲▲
-
普通会员
2023/8/21 15:57:01
34楼:
但是有一点很有意思,因为bcb11.3的32位同时有bcc编译器和clang编译器,所以分别测了一下,居然差距很大 clang32测出来效率和delphi64一样9秒多 bcc32测出来是5秒多
此帖子包含附件: 大小: 42.1K
----------------------------------------------
-
作者:
2023/8/21 15:59:40
34楼:
@merced (merced),D12的64位取模改了,已经很快了
----------------------------------------------
-
作者:
hectic (村雨Hectic)
▲▲▲▲▲
-
普通会员
2023/8/21 16:00:09
35楼:
to merced: 原来如此,多谢多谢。emb应该急着追赶版本迭代,没工夫去优化了。
----------------------------------------------
-
作者:
2023/8/21 16:17:00
36楼:
Delphi的32位编译器会把UInt64的除法取模动作翻译成调用_lludiv和_llumod两个汇编函数,64位则会直接编译成div或idiv指令,理论上后者会快不少。
----------------------------------------------
欢迎使用CnPack IDE Wizards http://www.cnpack.org/
作者:
2023/8/21 16:26:28
37楼:
D12取模优化了,不用div了,我的电脑比D11快6倍
此帖子包含附件: 大小: 57.6K
----------------------------------------------
-
作者:
2023/8/21 17:01:15
38楼:
to hq200306: mul然后shr,一目了然 这个早该改进的地方Embarcadero终于改进了,值得鼓励 :-)
----------------------------------------------
-
作者:
kwer (★★★★★)
★☆☆☆☆
-
普通会员
2023/8/21 17:09:17
38楼:
好帖,点赞了。
----------------------------------------------
==========-==========-==========-==========-========== 多隆, 给我备一匹最快的马, 我有事要走先~~~ ==========-==========-==========-==========-==========
作者:
2023/8/21 17:25:48
18楼:
比较菜,为什么 for num := 1 to 1000000000 Do这一句执行不过去?
----------------------------------------------
-
作者:
2023/8/21 18:47:20
39楼:
Delphi 11.3, release 模式 Win32: pass=3515 Win64: pass=3922
----------------------------------------------
-
作者:
2023/8/21 19:08:31
40楼:
把UInt64换成Integer,Win32,win64都缩短到23xx 看来还是UInt64的处理有问题
----------------------------------------------
-
作者:
2023/8/21 19:36:20
41楼:
@kentty (kentty),不一样,integer计算结果是错的
----------------------------------------------
-
作者:
2023/8/21 19:37:54
42楼:
不是有人說了, 看它的ASSEMBLY 就知差在哪裏了。
----------------------------------------------
-
作者:
hectic (村雨Hectic)
▲▲▲▲▲
-
普通会员
2023/8/21 20:56:34
43楼:
to kentty: 正确的计算结果是 233333334166666668 除了uint64,其他类型装不下这个数字,哪怕int64也不行
----------------------------------------------
-
作者:
2023/8/22 12:27:17
44楼:
不好意思,只盯着pass的数值,忘了total算得对不对了 :) 本来是想说, Delphi 11.3在Win32和Win64下对UInt64的处理效率差别不大, Win64慢10%,相比Win32并没有几倍的差距,也许是测试环境的其他差异, 按说Win64环境处理UInt64要比Win32少一次Move,至少不应该更慢; 换成Int32,在循环次数不变的情况下Win32/64总耗时都减少50% 看起来Delphi对UInt64取模的算法需要优化的地方还很多
----------------------------------------------
-
作者:
2023/8/22 13:14:05
45楼:
既然新版本的优化方式已经了解,那么对于老版本,可以用同样的方法来优化: function FastMod3(A: NativeUInt): NativeUInt; inline; const B = 3; C = (UInt64(1) shl 32) div B + UInt64(Boolean((UInt64(1) shl 32) mod B)); begin Result := A - B * ((A*C) shr 32); end; function FastMod5(A: NativeUInt): NativeUInt; inline; const B = 5; C = (UInt64(1) shl 32) div B + UInt64(Boolean((UInt64(1) shl 32) mod B)); begin Result := A - B * ((A*C) shr 32); end;
----------------------------------------------
-
作者:
vga (vga)
★☆☆☆☆
-
盒子活跃会员
2023/8/22 15:46:27
46楼:
我的 C++Builder11.3 不支持 UInt64 要写成 System::UInt64 unsigned long long num, total, pass; unsigned __int64 num, total, pass; System::UInt64 num, total, pass;
----------------------------------------------
-
作者:
2023/8/22 19:15:47
47楼:
我也顺便试了下,在我的电脑上 FPC 3.3.1 编译的程序比 Delphi 11.3 编译的快4倍多点
此帖子包含附件: 大小: 25.0K
----------------------------------------------
-
作者:
2023/8/22 19:47:35
48楼:
@bluestorm8 Result := A - B * ((A*C) shr 32)里面A*C和B*U64会不会溢出?
----------------------------------------------
-
作者:
2023/8/22 20:25:02
49楼:
以前, D7 時, FPC 是無法和DELPHI 比, 不管COMPILE 或 RUN。 現在則反過來了。 所以說, EMB 真的不行。
----------------------------------------------
-
作者:
hectic (村雨Hectic)
▲▲▲▲▲
-
普通会员
2023/8/22 21:54:33
50楼:
powerpcer: fpc还支持lambda,现在主流语言哪个不支持lambda,虽然fpc没有c++那么灵活,但是好歹支持了,delphi虽然可以用type reference来代替,但是写起来还是麻烦一些。
----------------------------------------------
-
作者:
2023/8/22 22:17:05
51楼:
一個軟體 software 的重點,在使用者來看是: 1. 正確 correctness 2. 穏定 robust 3. 跑得快 fast COMPILER+FRAMEWORK/LIBRARY 是一種軟體。 以開發人員的角度來看是: 1. Bug Free (compiler/framework/library) 2. IDE Robust 3. compile fast lambda 不lambda 真的是個沒興趣,正如之前也一堆人 在追REACT 一樣,脫褲子放屁的東西。 還有一些 Template metaprogramming 控是一樣的,你自己心爽就好。 這和你的 PRODUCT QUALITY 沒啥關係。 正如之前大家也吹過好一陣子GO,說GO 高拼發。 結果現在呢? 你拼發了沒? 工具而已。吹就是為了出來當老大。說上幾句話。 什麼貓都好,抓到老鼠才是重點。 但compiler 這隻貓,並不會自動抓,抓的人還是你。
----------------------------------------------
-
作者:
2023/8/23 2:28:43
52楼:
lambda 这种语法糖,其实并不是好东西。可能用 JavaScript 那帮人比较喜欢。因为 JavaScript 可以胡乱写,连类的定义都可以写到中途做更改,看似很灵活,写的时候爽,读的时候,Debug 的时候就难受了。 语法规则越多,越不好。语法规则简单才是好的。
----------------------------------------------
-
作者:
2023/8/23 7:15:14
53楼:
mod 3 和 mod 5 的算法思想: mod 3: 将数字的每一位加起来,如果是 3 的倍数,这个数就可以被 3 整除。 例如:34567,3+4+5+6+7=25,2+5=7;7被3除,余数为1;所以:34567 mod 3 = 1; 例如:23564,2+3+5+6+4=20,2+0=2;2被3除,余数为2;所以:23564 mod 3 = 2; mod 5: 最后一位数字(个位)是 0 或 5,就可以被 5 整除。 例如:12898978,12898975肯定可以被5整除,所以余数是:3(8 - 5 = 3); 例如:12898972,12898970肯定可以被5整除,所以余数是:2; 判断个位是否大于5就可以了; 程序大家自己动手写写,看谁写的效率最高。
----------------------------------------------
武汉天气不好
作者:
2023/8/23 8:50:46
54楼:
@kentty(40楼) FastMod3和FastMod5的参数A实际上最多只能是32Bit整数,如果是大于32bit,可能会溢出。 使用NativeUInt的原因是64bit程序使用64bit的A比较快、32bit程序使用32bit的A比较快,这完全是出于性能考量。 对于Result := A - B * ((A*C) shr 32), 等号的右面是使用64Bit运算,如果B只是一个32bit大小的数据,由于Result只是A对B的余数,因此result <= B-1, 不会溢出。
----------------------------------------------
-
作者:
biznow (biznow)
★☆☆☆☆
-
盒子活跃会员
2023/8/23 9:03:54
55楼:
我测试了Linux的情况,比Windows快了3+倍。
此帖子包含附件: 大小: 8.8K
----------------------------------------------
-
作者:
hectic (村雨Hectic)
▲▲▲▲▲
-
普通会员
2023/8/23 10:20:32
56楼:
to dbyoung: 算法优化的办法肯定有啊,老外那个帖子里有,你看看这个,小于1ms就得出答案了。 我用的lazarus,因为delphi我暂时换成了bcb,社区版安装没法共存,delphi如果用这个优化后的算法肯定也是小于1ms速度。 但是这不是问题的关键,我们并不是为了找优化算法,而是我们发现emb对11.3之前的d64的div没有做任何优化。
此帖子包含附件: 大小: 102.7K
----------------------------------------------
-
作者:
2023/8/24 13:47:59
57楼:
DCC64和BCC64一样后台都转成5.0的LLVM的IL了,速度一样,慢正常 D12的LLVM升级到15以后了,速度优化会快很多 32位经典版确实要快点
----------------------------------------------
-
作者:
2023/8/24 14:06:45
58楼:
56楼的代码太赖皮了,如果只是为了求total,直接用等差数列求和公式就完事了 :)
----------------------------------------------
-