If you look at the ping report, the RT times (as printed) total 25 miliseconds; at the moment, I'm looking at RTs on the order of 90 milisecs. Either adds up to half a sec pretty fast -- just 6 (+/-) iterations in my case; 20 in yours.
BTW, your script requires mods/workaround beyond my ken for Windoze/AS 5.12...: Your vendor has not defined POSIX macro WUNTRACED, used at F:\_Perl_\pl_test\940785.pl at my equivalent of your line 45.
sleep has a resolution of one second. It means it can trigger anywhere in that one second and therefore on the average it will be 0.5 seconds "off" the exact mark.
A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James