Account Options

  1. Sign in
The old Google Groups will be going away soon, but your browser is incompatible with the new version.
Google Groups Home
« Groups Home
Perl Help su strano comportamento di chiamata system (Crosspot con lang.perl e linux.iniziare)
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  1 message - Collapse all  -  Translate all to Translated (View all originals)
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
bc  
View profile   Translate to Translated (View Original)
 More options Nov 22 2011, 12:12 pm
Newsgroups: it.comp.lang.perl, it.comp.os.linux.iniziare
From: bc <n...@none.none>
Date: Tue, 22 Nov 2011 18:12:49 +0100
Local: Tues, Nov 22 2011 12:12 pm
Subject: Perl Help su strano comportamento di chiamata system (Crosspot con lang.perl e linux.iniziare)
Crosspot con lang.perl e linux.iniziare perche non capisco se dipenda da
linux o da perl

Ho un problema a leggere il tempo impiegato da una chiamata a system
(stesso comportamento anche con apici inversi o con open)

Volevo leggere dei blocchi di disco fisso e confrontare il tempo di
lettura fra un blocco e l'altro. L'idea era che se il tempo si alza
molto, probabilmente il Disco si legge male. (si conosco badblocks e i
derivati di smartctl, ma sono paranoico e volevo anche un altro parere)

Sotto c'è un codice di prova grezzo. Funziona leggendo 1024 blocchi di
512b alla volta da /dev/sda e li ignora gettandoli in /dev/null.
Concettualmente funziona, ma il flusso è "pompante" e le differenze fra
lettura minima e massima sono falsate da qualche ottimizzazione.

si va da 0,04 secondi a 20 Secondi... (lo si vede ad occhio anche da
come fa lo scrolling che funziona in modo anomalo)

mentre nell'output di dd la differenza è molto minore.

Sul mio sistema
dd riporta un valore tipico di 750MB/S
Con qualche 500MB/S e con qualche 1.7 GB/S
A questa differenza riesco a dare un senso, immagino sia l'influenza
della chace del disco.

ma è l'altra differenza non la capisco.
Tipicamente fa  dalle 4 alle 8 letture a 0.04 e una a 5 secondi, ogni
tanto qualcuna a 10 e almeno una l'ha fatta a 20

Mi piacerebbe capire da cosa dipende e se si può evitare il problema. Il
programma è da raffinare, ma non mi sembra che sia sbagliato.

Se non c'è modo di regolarizzare il flusso, anzichè calcolare il tempo,
leggerò l'output di "dd" però volevo tenerlo come ultima spiaggia.

ps... Ho provato anche con:
hdparm --read-sector NUMERO /dev/sda > /dev/null
Ma legge un settore alla volta (se può leggerne di piu' non ho capito
come) e risulta troppo lento.

DI SEGUITO IL CODICE
--------------------------------
#!/usr/bin/perl -w
use Time::HiRes qw(usleep ualarm gettimeofday tv_interval);
use POSIX qw/floor/;

my @aSect=`hdparm -N /dev/sda`;
my $maxsect;
my $line;
$line=($aSect[2]);
chomp($line);
$line=~ s/^\s+//; #lTrim
$line=~ s/\s+$//; #rTrim
print "3 $line\n";
my $fh    = *STDERR;
$min=1000;
$max=0;
if ($line =~ m/= ([0-9]+)/ ){
        $maxsect=$1;
        $max1024=$maxsect/1024; #Leggo 1024 settori alla volta non importa se
l'ultimo è sgaffo, DD non si offende
        print "$max1024\n";
        $intmax1024=floor($max1024);
        $rest=$intmax1024;
        #die "ERRORE Divisione non intera $intmax1024 <> $max1024\n" if
($intmax1024 != $max1024);
        #die "FINITO\n";
        for (my $i = 0; $i < $intmax1024; $i++) {
                #$test="hdparm --read-sector $i /dev/sda > /dev/null"; Troppo lento
                $test="sudo dd if=/dev/sda of=/dev/null count=1024 bs=512 skip=$i";
                $t0=[gettimeofday];
                #my ($exitstatus,@aRet)=pipecommand($test);
                system ($test); #Sporca output
                $elapsed=tv_interval($t0, [gettimeofday]);
                $err=$?;
                $min=$elapsed if ($min>$elapsed) ;
                $max=$elapsed if ($elapsed>$max) ;
                if ($exitstatus){
                        die "ERRORE SETTORE $i , Errore Restituito: $err \n";
                }
                $rest-=1;
                #my $ticktock = clock();
                #$rest $elapsed
                $previsto=($elapsed*$rest)/3600;
                printf $fh "$rest    $elapsed   $min   $max   $previsto              \n";
        }

}

sub pipecommand{
        my ($cmd)=@_;
        my($fh,@retcommand);
        open $fh, $cmd." 2>&1 |"   or die "Couldn't execute program: $!";
        while ( defined(my $line = <$fh>)  ) {
                chomp($line);
                push(@retcommand,$line);
                #&logfunc("retcmd",$line);
        }
        close $fh;
        my $exitStat=$?;
        #&logfunc("retcmd","TERMINATO: Exit Status = $exitStat");
        return ($exitStat,@retcommand);
}

#$ dd if=/dev/zero of=/dev/null $ count 1024 bs=64k
#256*512
#sudo dd if=/dev/sda of=pippo count=1 bs=131072

 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
End of messages
« Back to Discussions « Newer topic     Older topic »