UnixBench分数计算与多进程测试

在支持较好的测试机上直接运行RUN脚本即可得到测试结果

测试结果(部分)

   BYTE UNIX Benchmarks (Version 5.1.3)
------------------------------------------------------------------------
Benchmark Run: Wed Aug 07 2024 17:02:28 - 17:30:33
8 CPUs in system; running 1 parallel copy of tests

Dhrystone 2 using register variables       57732243.9 lps   (10.0 s, 7 samples)
Double-Precision Whetstone                     9863.5 MWIPS (9.9 s, 7 samples)
Execl Throughput                                270.8 lps   (30.0 s, 2 samples)
File Copy 1024 bufsize 2000 maxblocks          2036.0 KBps  (30.0 s, 2 samples)
File Copy 256 bufsize 500 maxblocks             492.0 KBps  (30.0 s, 2 samples)
File Copy 4096 bufsize 8000 maxblocks          8573.2 KBps  (30.0 s, 2 samples)
Pipe Throughput                             3224999.0 lps   (10.0 s, 7 samples)
Pipe-based Context Switching                  10965.9 lps   (10.0 s, 7 samples)
Process Creation                               6449.4 lps   (30.0 s, 2 samples)
Shell Scripts (1 concurrent)                   1037.6 lpm   (60.1 s, 2 samples)
Shell Scripts (8 concurrent)                    559.1 lpm   (60.1 s, 2 samples)
System Call Overhead                        3044508.5 lps   (10.0 s, 7 samples)

System Benchmarks Index Values               BASELINE       RESULT    INDEX
Dhrystone 2 using register variables         116700.0   57732243.9   4947.1
Double-Precision Whetstone                       55.0       9863.5   1793.4
Execl Throughput                                 43.0        270.8     63.0
File Copy 1024 bufsize 2000 maxblocks          3960.0       2036.0      5.1
File Copy 256 bufsize 500 maxblocks            1655.0        492.0      3.0
File Copy 4096 bufsize 8000 maxblocks          5800.0       8573.2     14.8
Pipe Throughput                               12440.0    3224999.0   2592.4
Pipe-based Context Switching                   4000.0      10965.9     27.4
Process Creation                                126.0       6449.4    511.9
Shell Scripts (1 concurrent)                     42.4       1037.6    244.7
Shell Scripts (8 concurrent)                      6.0        559.1    931.9
System Call Overhead                          15000.0    3044508.5   2029.7
                                                                   ========
System Benchmarks Index Score                                         189.4

------------------------------------------------------------------------
Benchmark Run: Wed Aug 07 2024 17:30:33 - 17:58:43
8 CPUs in system; running 8 parallel copies of tests

Dhrystone 2 using register variables      438641213.0 lps   (10.0 s, 7 samples)
Double-Precision Whetstone                    75079.1 MWIPS (9.7 s, 7 samples)
Execl Throughput                               3092.1 lps   (29.9 s, 2 samples)
File Copy 1024 bufsize 2000 maxblocks         19974.9 KBps  (30.0 s, 2 samples)
File Copy 256 bufsize 500 maxblocks            5061.5 KBps  (30.0 s, 2 samples)
File Copy 4096 bufsize 8000 maxblocks         75627.0 KBps  (30.0 s, 2 samples)
Pipe Throughput                            25578987.9 lps   (10.0 s, 7 samples)
Pipe-based Context Switching                3692847.5 lps   (10.0 s, 7 samples)
Process Creation                              62683.6 lps   (30.0 s, 2 samples)
Shell Scripts (1 concurrent)                   4688.8 lpm   (60.1 s, 2 samples)
Shell Scripts (8 concurrent)                    822.1 lpm   (60.2 s, 2 samples)
System Call Overhead                       24022012.0 lps   (10.0 s, 7 samples)

System Benchmarks Index Values               BASELINE       RESULT    INDEX
Dhrystone 2 using register variables         116700.0  438641213.0  37587.1
Double-Precision Whetstone                       55.0      75079.1  13650.7
Execl Throughput                                 43.0       3092.1    719.1
File Copy 1024 bufsize 2000 maxblocks          3960.0      19974.9     50.4
File Copy 256 bufsize 500 maxblocks            1655.0       5061.5     30.6
File Copy 4096 bufsize 8000 maxblocks          5800.0      75627.0    130.4
Pipe Throughput                               12440.0   25578987.9  20561.9
Pipe-based Context Switching                   4000.0    3692847.5   9232.1
Process Creation                                126.0      62683.6   4974.9
Shell Scripts (1 concurrent)                     42.4       4688.8   1105.8
Shell Scripts (8 concurrent)                      6.0        822.1   1370.1
System Call Overhead                          15000.0   24022012.0  16014.7
                                                                   ========
System Benchmarks Index Score                                        1858.7

需要重点关注的是RESULT INDEX两列以及最终得分System Benchmarks Index Score

单进程测试(简化版shell代码)

######################  单核测试 ##########################
echo "Dhrystone 2 using register variables"
./dhry2reg 10                 # 结果除以10
echo "Double-Precision Whetstone"
./whetstone-double 10
# ./execl 30
echo "File Copy 1024 bufsize 2000 maxblocks"
./fstime -c -t 30 -d ../tmp/ -b 1024 -m 2000
echo "File Copy 256 bufsize 500 maxblocks"
./fstime -c -t 30 -d ../tmp/ -b 256 -m 500
echo "File Copy 4096 bufsize 8000 maxblocks"
./fstime -c -t 30 -d ../tmp/ -b 4096 -m 8000  
echo "Pipe Throughput"
./pipe 10             # 结果除以10
echo "Pipe-based Context Switching"
./context1 10         # 结果除以10
echo "Process Creation"
./spawn 30            # 结果除以30

分数计算规则(源码解析)

sub indexResults {
    my ( $results ) = @_;

    # Read in the baseline result data.  If we can't get it, just return
    # without making indexed results.
    my $index = readResultsFromFile($BINDIR . "/index.base");
    if (!defined($index)) {
        return;
    }

    # Count the number of results we have (indexed or not) in
    # each category.
    my $numCat = { };
    foreach my $bench (@{$results->{'list'}}) {
        my $bresult = $results->{$bench};
        ++$numCat->{$bresult->{'cat'}};
    }
    $results->{'numCat'} = $numCat;

    my $numIndex = { };
    my $indexed = { };
    my $sum = { };
    foreach my $bench (sort(keys(%$index))) {
        # Get the test data for this benchmark.
        my $tdata = $testParams->{$bench};
        if (!defined($tdata)) {
            abortRun("unknown benchmark \"$bench\" in $BINDIR/index.base");
        }

        # Get the test category.  Count the total tests in this cat.
        my $cat = $tdata->{'cat'};
        ++$numIndex->{$cat};

        # If we don't have a result for this test, skip.
        next if (!defined($results->{$bench}));

        # Get the index and actual results.  Calcluate the score.
        my $iresult = $index->{$bench};
        my $bresult = $results->{$bench};
        my $ratio = $bresult->{'score'} / $iresult->{'score'};

        # Save the indexed score.
        $bresult->{'iscore'} = $iresult->{'score'};
        $bresult->{'index'} = $ratio * 10;

        # Sun the scores, and count this test for this category.
        $sum->{$cat} += log($ratio) if ($ratio > 0.000001);
        ++$indexed->{$cat};
    }

    # Calculate the index scores per category.
    $results->{'indexed'} = $indexed;
    $results->{'numIndex'} = $numIndex;
    foreach my $c (keys(%$indexed)) {
        if ($indexed->{$c} > 0) {
            $results->{'index'}{$c} = exp($sum->{$c} / $indexed->{$c}) * 10;
        }
    }
}

测试得到的RESULT 并不是最后的打分结果,这里需要进行基准矫正得分,UnixBench 对一台基准测试机器进行测试得到其性能结果(即BASELINE 那一列),并设定其分值为10,因此INDEX得分是RESULT / BASELINE * 10

最终的System Benchmarks Index Score计算公式为:exp(sum(log(manycores_score_list))/total_test_nums)

其中manycores_score_list表示RESULT列的结果,total_test_nums表示测试项数目,目前官方标准测试项目数为12

多进程测试相关代码

# Execute a benchmark command.  We set off a given number of copies in
# parallel to exercise multiple CPUs.
#
# We return an array of results hashes, one per copy; each one is as
# returned by readResults().
sub executeBenchmark {
    my ( $command, $copies ) = @_;

    # Array of contexts for all the copies we're running.
    my $ctxt = [ ];

    # Kick off all the commands at once.
    for (my $i = 0; $i < $copies; ++$i) {
        my ( $cmdPid, $cmdFd ) = commandBuffered($command);
        $ctxt->[$i] = {
            'pid'     => $cmdPid,
            'fd'      => $cmdFd,
        };
    }

    # Now, we can simply read back the command results in order.  Because
    # the child processes read and buffer the results and time the commands,
    # there's no need to use select() to read the results as they appear.
    my $pres = [ ];
    for (my $i = 0; $i < $copies; ++$i) {
        my $presult = readResults($ctxt->[$i]{'pid'}, $ctxt->[$i]{'fd'});
        push(@$pres, $presult);
    }

    $pres;
}
# Exec the given command in a sub-process.
#
# In the child process, we run the command and store its standard output.
# We also time its execution, and catch its exit status.  We then write
# the command's output, plus lines containing the execution time and status,
# to a pipe.
#
# In the parent process, we immediately return an array containing the
# child PID and the filehandle to the pipe.  This allows the caller to
# kick off multiple commands in parallel, then gather their output.
sub commandBuffered {
    my ( $cmd ) = @_;

    # Create a pipe for parent-child communication.
    my $childReader;
    my $parentWriter;
    pipe($childReader, $parentWriter) || abortRun("pipe() failed");
    $parentWriter->autoflush(1);

    # Fork off the child process.
    my $pid = fork();
    if (!defined($pid)) {
        abortRun("fork() failed (undef)");
    } elsif ($pid == 0) {
        # Close the other end of the pipe.
        close $childReader;

        # Start the clock and spawn the command.
        my $benchStart = Time::HiRes::time();
        my ( $cmdPid, $cmdFd ) = command($cmd);

        # Read and buffer all the command's output.
        my $output = [ ];
        while (<$cmdFd>) {
            push(@$output, $_);
        }

        # Stop the clock and save the time.
        my $elTime = Time::HiRes::time() - $benchStart;
        push(@$output, sprintf "elapsed|%f\n", $elTime);

        # Wait for the child to die so we can get its status.
        # close($cmdFd);  Doesn't work???
        waitpid($cmdPid, 0);
        my $status = $?;
        push(@$output, sprintf "status|%d\n", $status);

        # Now that we've got the time, play back all the output to the pipe.
        # The parent can read this at its leisure.
        foreach my $line (@$output) {
            print $parentWriter $line;
        }

        # Terminate this child.
        close $parentWriter;
        exit(0);
    }

    # Close the other end of the pipe.
    close $parentWriter;

    return ( $pid, $childReader );
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值