mirror of
https://github.com/kdlucas/byte-unixbench.git
synced 2024-12-11 23:30:07 +08:00
Version 5.1.2.
This commit is contained in:
commit
f53eadaa3e
245
UnixBench/.cproject
Normal file
245
UnixBench/.cproject
Normal file
@ -0,0 +1,245 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<?fileVersion 4.0.0?>
|
||||
|
||||
<cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
|
||||
<storageModule moduleId="org.eclipse.cdt.core.settings">
|
||||
<cconfiguration id="cdt.managedbuild.config.gnu.exe.debug.1112988852">
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.exe.debug.1112988852" moduleId="org.eclipse.cdt.core.settings" name="Debug">
|
||||
<externalSettings/>
|
||||
<extensions>
|
||||
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="org.eclipse.cdt.core.MakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
</extensions>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<configuration artifactName="UnixBench" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.debug.1112988852" name="Debug" parent="cdt.managedbuild.config.gnu.exe.debug">
|
||||
<folderInfo id="cdt.managedbuild.config.gnu.exe.debug.1112988852." name="/" resourcePath="">
|
||||
<toolChain id="cdt.managedbuild.toolchain.gnu.exe.debug.1265656843" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.debug">
|
||||
<targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.debug.724460794" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.debug"/>
|
||||
<builder buildPath="${workspace_loc:/UnixBench/Debug}" id="cdt.managedbuild.target.gnu.builder.exe.debug.1915020561" managedBuildOn="true" name="Gnu Make Builder.Debug" superClass="cdt.managedbuild.target.gnu.builder.exe.debug"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.archiver.base.237653783" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug.292688199" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug">
|
||||
<option id="gnu.cpp.compiler.exe.debug.option.optimization.level.1386988579" superClass="gnu.cpp.compiler.exe.debug.option.optimization.level" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/>
|
||||
<option id="gnu.cpp.compiler.exe.debug.option.debugging.level.2099186456" superClass="gnu.cpp.compiler.exe.debug.option.debugging.level" value="gnu.cpp.compiler.debugging.level.max" valueType="enumerated"/>
|
||||
</tool>
|
||||
<tool id="cdt.managedbuild.tool.gnu.c.compiler.exe.debug.1624622538" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.exe.debug">
|
||||
<option defaultValue="gnu.c.optimization.level.none" id="gnu.c.compiler.exe.debug.option.optimization.level.2086155431" superClass="gnu.c.compiler.exe.debug.option.optimization.level" valueType="enumerated"/>
|
||||
<option id="gnu.c.compiler.exe.debug.option.debugging.level.1302569694" superClass="gnu.c.compiler.exe.debug.option.debugging.level" value="gnu.c.debugging.level.max" valueType="enumerated"/>
|
||||
</tool>
|
||||
<tool id="cdt.managedbuild.tool.gnu.c.linker.exe.debug.623082859" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.debug"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug.744081279" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.assembler.exe.debug.1447287939" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.debug"/>
|
||||
</toolChain>
|
||||
</folderInfo>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="scannerConfiguration">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="makefileGenerator">
|
||||
<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'gcc -E -P -v -dD "${plugin_state_location}/${specs_file}"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'g++ -E -P -v -dD "${plugin_state_location}/specs.cpp"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'gcc -E -P -v -dD "${plugin_state_location}/specs.c"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
</cconfiguration>
|
||||
<cconfiguration id="cdt.managedbuild.config.gnu.exe.release.187171772">
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.exe.release.187171772" moduleId="org.eclipse.cdt.core.settings" name="Release">
|
||||
<externalSettings/>
|
||||
<extensions>
|
||||
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="org.eclipse.cdt.core.MakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
</extensions>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<configuration artifactName="UnixBench" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.release.187171772" name="Release" parent="cdt.managedbuild.config.gnu.exe.release">
|
||||
<folderInfo id="cdt.managedbuild.config.gnu.exe.release.187171772." name="/" resourcePath="">
|
||||
<toolChain id="cdt.managedbuild.toolchain.gnu.exe.release.804230130" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.release">
|
||||
<targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.release.1333474325" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.release"/>
|
||||
<builder buildPath="${workspace_loc:/UnixBench/Release}" id="cdt.managedbuild.target.gnu.builder.exe.release.334311293" managedBuildOn="true" name="Gnu Make Builder.Release" superClass="cdt.managedbuild.target.gnu.builder.exe.release"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.archiver.base.748606689" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.1158097705" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release">
|
||||
<option id="gnu.cpp.compiler.exe.release.option.optimization.level.114803414" superClass="gnu.cpp.compiler.exe.release.option.optimization.level" value="gnu.cpp.compiler.optimization.level.most" valueType="enumerated"/>
|
||||
<option id="gnu.cpp.compiler.exe.release.option.debugging.level.1266303819" superClass="gnu.cpp.compiler.exe.release.option.debugging.level" value="gnu.cpp.compiler.debugging.level.none" valueType="enumerated"/>
|
||||
</tool>
|
||||
<tool id="cdt.managedbuild.tool.gnu.c.compiler.exe.release.50008527" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.exe.release">
|
||||
<option defaultValue="gnu.c.optimization.level.most" id="gnu.c.compiler.exe.release.option.optimization.level.1611735628" superClass="gnu.c.compiler.exe.release.option.optimization.level" valueType="enumerated"/>
|
||||
<option id="gnu.c.compiler.exe.release.option.debugging.level.1010649020" superClass="gnu.c.compiler.exe.release.option.debugging.level" value="gnu.c.debugging.level.none" valueType="enumerated"/>
|
||||
</tool>
|
||||
<tool id="cdt.managedbuild.tool.gnu.c.linker.exe.release.1604769908" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.release"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.cpp.linker.exe.release.1185527108" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.exe.release"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.assembler.exe.release.211377571" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.release"/>
|
||||
</toolChain>
|
||||
</folderInfo>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="scannerConfiguration">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="makefileGenerator">
|
||||
<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'gcc -E -P -v -dD "${plugin_state_location}/${specs_file}"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'g++ -E -P -v -dD "${plugin_state_location}/specs.cpp"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'gcc -E -P -v -dD "${plugin_state_location}/specs.c"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
</storageModule>
|
||||
</cconfiguration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<project id="UnixBench.cdt.managedbuild.target.gnu.exe.570459259" name="Executable" projectType="cdt.managedbuild.target.gnu.exe"/>
|
||||
</storageModule>
|
||||
</cproject>
|
82
UnixBench/.project
Normal file
82
UnixBench/.project
Normal file
@ -0,0 +1,82 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>UnixBench</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
|
||||
<triggers>clean,full,incremental,</triggers>
|
||||
<arguments>
|
||||
<dictionary>
|
||||
<key>?name?</key>
|
||||
<value></value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.append_environment</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.autoBuildTarget</key>
|
||||
<value>all</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.buildArguments</key>
|
||||
<value></value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.buildCommand</key>
|
||||
<value>make</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.buildLocation</key>
|
||||
<value>${workspace_loc:/UnixBench/Debug}</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.cleanBuildTarget</key>
|
||||
<value>clean</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.contents</key>
|
||||
<value>org.eclipse.cdt.make.core.activeConfigSettings</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.enableAutoBuild</key>
|
||||
<value>false</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.enableCleanBuild</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.enableFullBuild</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.fullBuildTarget</key>
|
||||
<value>all</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.stopOnError</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.cdt.core.cnature</nature>
|
||||
<nature>org.eclipse.cdt.core.ccnature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
252
UnixBench/Makefile
Normal file
252
UnixBench/Makefile
Normal file
@ -0,0 +1,252 @@
|
||||
##############################################################################
|
||||
# UnixBench v5.1.1
|
||||
# Based on The BYTE UNIX Benchmarks - Release 3
|
||||
# Module: Makefile SID: 3.9 5/15/91 19:30:15
|
||||
#
|
||||
##############################################################################
|
||||
# Bug reports, patches, comments, suggestions should be sent to:
|
||||
# David C Niemi <niemi@tux.org>
|
||||
#
|
||||
# Original Contacts at Byte Magazine:
|
||||
# Ben Smith or Tom Yager at BYTE Magazine
|
||||
# bensmith@bytepb.byte.com tyager@bytepb.byte.com
|
||||
#
|
||||
##############################################################################
|
||||
# Modification Log: 7/28/89 cleaned out workload files
|
||||
# 4/17/90 added routines for installing from shar mess
|
||||
# 7/23/90 added compile for dhrystone version 2.1
|
||||
# (this is not part of Run file. still use old)
|
||||
# removed HZ from everything but dhry.
|
||||
# HZ is read from the environment, if not
|
||||
# there, you must define it in this file
|
||||
# 10/30/90 moved new dhrystone into standard set
|
||||
# new pgms (dhry included) run for a specified
|
||||
# time rather than specified number of loops
|
||||
# 4/5/91 cleaned out files not needed for
|
||||
# release 3 -- added release 3 files -ben
|
||||
# 10/22/97 added compiler options for strict ANSI C
|
||||
# checking for gcc and DEC's cc on
|
||||
# Digital Unix 4.x (kahn@zk3.dec.com)
|
||||
# 09/26/07 changes for UnixBench 5.0
|
||||
# 09/30/07 adding ubgears, GRAPHIC_TESTS switch
|
||||
# 10/14/07 adding large.txt
|
||||
##############################################################################
|
||||
|
||||
##############################################################################
|
||||
# CONFIGURATION
|
||||
##############################################################################
|
||||
|
||||
SHELL = /bin/sh
|
||||
|
||||
# GRAPHICS TESTS: Uncomment the definition of "GRAPHIC_TESTS" to enable
|
||||
# the building of the graphics benchmarks. This will require the
|
||||
# X11 libraries on your system.
|
||||
#
|
||||
# Comment the line out to disable these tests.
|
||||
GRAPHIC_TESTS = defined
|
||||
|
||||
# Set "GL_LIBS" to the libraries needed to link a GL program.
|
||||
GL_LIBS = -lGL -lXext -lX11
|
||||
|
||||
|
||||
# COMPILER CONFIGURATION: Set "CC" to the name of the compiler to use
|
||||
# to build the binary benchmarks. You should also set "$cCompiler" in the
|
||||
# Run script to the name of the compiler you want to test.
|
||||
CC=gcc
|
||||
|
||||
# OPTIMISATION SETTINGS:
|
||||
|
||||
## Very generic
|
||||
#OPTON = -O
|
||||
|
||||
## For Linux 486/Pentium, GCC 2.7.x and 2.8.x
|
||||
#OPTON = -O2 -fomit-frame-pointer -fforce-addr -fforce-mem -ffast-math \
|
||||
# -m486 -malign-loops=2 -malign-jumps=2 -malign-functions=2
|
||||
|
||||
## For Linux, GCC previous to 2.7.0
|
||||
#OPTON = -O2 -fomit-frame-pointer -fforce-addr -fforce-mem -ffast-math -m486
|
||||
|
||||
#OPTON = -O2 -fomit-frame-pointer -fforce-addr -fforce-mem -ffast-math \
|
||||
# -m386 -malign-loops=1 -malign-jumps=1 -malign-functions=1
|
||||
|
||||
## For Solaris 2, or general-purpose GCC 2.7.x
|
||||
OPTON = -O2 -fomit-frame-pointer -fforce-addr -ffast-math -Wall
|
||||
|
||||
## For Digital Unix v4.x, with DEC cc v5.x
|
||||
#OPTON = -O4
|
||||
#CFLAGS = -DTIME -std1 -verbose -w0
|
||||
|
||||
## generic gcc CFLAGS. -DTIME must be included.
|
||||
CFLAGS = -DTIME -Wall -pedantic -ansi
|
||||
|
||||
|
||||
##############################################################################
|
||||
# END CONFIGURATION
|
||||
##############################################################################
|
||||
|
||||
|
||||
# local directories
|
||||
PROGDIR = ./pgms
|
||||
SRCDIR = ./src
|
||||
TESTDIR = ./testdir
|
||||
RESULTDIR = ./results
|
||||
TMPDIR = ./tmp
|
||||
# other directories
|
||||
INCLDIR = /usr/include
|
||||
LIBDIR = /lib
|
||||
SCRIPTS = unixbench.logo multi.sh tst.sh index.base
|
||||
SOURCES = arith.c big.c context1.c \
|
||||
dummy.c execl.c \
|
||||
fstime.c hanoi.c \
|
||||
pipe.c spawn.c \
|
||||
syscall.c looper.c timeit.c time-polling.c \
|
||||
dhry_1.c dhry_2.c dhry.h whets.c ubgears.c
|
||||
TESTS = sort.src cctest.c dc.dat large.txt
|
||||
|
||||
ifdef GRAPHIC_TESTS
|
||||
GRAPHIC_BINS = $(PROGDIR)/ubgears
|
||||
else
|
||||
GRAPHIC_BINS =
|
||||
endif
|
||||
|
||||
# Program binaries.
|
||||
BINS = $(PROGDIR)/arithoh $(PROGDIR)/register $(PROGDIR)/short \
|
||||
$(PROGDIR)/int $(PROGDIR)/long $(PROGDIR)/float $(PROGDIR)/double \
|
||||
$(PROGDIR)/hanoi $(PROGDIR)/syscall $(PROGDIR)/context1 \
|
||||
$(PROGDIR)/pipe $(PROGDIR)/spawn $(PROGDIR)/execl \
|
||||
$(PROGDIR)/dhry2 $(PROGDIR)/dhry2reg $(PROGDIR)/looper \
|
||||
$(PROGDIR)/fstime $(PROGDIR)/whetstone-double $(GRAPHIC_BINS)
|
||||
## These compile only on some platforms...
|
||||
# $(PROGDIR)/poll $(PROGDIR)/poll2 $(PROGDIR)/select
|
||||
|
||||
# Required non-binary files.
|
||||
REQD = $(BINS) $(PROGDIR)/unixbench.logo \
|
||||
$(PROGDIR)/multi.sh $(PROGDIR)/tst.sh $(PROGDIR)/index.base \
|
||||
$(PROGDIR)/gfx-x11 \
|
||||
$(TESTDIR)/sort.src $(TESTDIR)/cctest.c $(TESTDIR)/dc.dat \
|
||||
$(TESTDIR)/large.txt
|
||||
|
||||
# ######################### the big ALL ############################
|
||||
all: distr programs
|
||||
## Ick!!! What is this about??? How about let's not chmod everything bogusly.
|
||||
# @chmod 744 * $(SRCDIR)/* $(PROGDIR)/* $(TESTDIR)/* $(DOCDIR)/*
|
||||
|
||||
# ####################### a check for Run ######################
|
||||
check: $(REQD)
|
||||
make all
|
||||
# ##############################################################
|
||||
# distribute the files out to subdirectories if they are in this one
|
||||
distr:
|
||||
@echo "Checking distribution of files"
|
||||
# scripts
|
||||
@if test ! -d $(PROGDIR) \
|
||||
; then \
|
||||
mkdir $(PROGDIR) \
|
||||
; mv $(SCRIPTS) $(PROGDIR) \
|
||||
; else \
|
||||
echo "$(PROGDIR) exists" \
|
||||
; fi
|
||||
# C sources
|
||||
@if test ! -d $(SRCDIR) \
|
||||
; then \
|
||||
mkdir $(SRCDIR) \
|
||||
; mv $(SOURCES) $(SRCDIR) \
|
||||
; else \
|
||||
echo "$(SRCDIR) exists" \
|
||||
; fi
|
||||
# test data
|
||||
@if test ! -d $(TESTDIR) \
|
||||
; then \
|
||||
mkdir $(TESTDIR) \
|
||||
; mv $(TESTS) $(TESTDIR) \
|
||||
; else \
|
||||
echo "$(TESTDIR) exists" \
|
||||
; fi
|
||||
# temporary work directory
|
||||
@if test ! -d $(TMPDIR) \
|
||||
; then \
|
||||
mkdir $(TMPDIR) \
|
||||
; else \
|
||||
echo "$(TMPDIR) exists" \
|
||||
; fi
|
||||
# directory for results
|
||||
@if test ! -d $(RESULTDIR) \
|
||||
; then \
|
||||
mkdir $(RESULTDIR) \
|
||||
; else \
|
||||
echo "$(RESULTDIR) exists" \
|
||||
; fi
|
||||
|
||||
programs: $(BINS)
|
||||
|
||||
# Individual programs
|
||||
$(PROGDIR)/arithoh: $(SRCDIR)/arith.c
|
||||
$(CC) -o $(PROGDIR)/arithoh ${CFLAGS} ${OPTON} -Darithoh $(SRCDIR)/arith.c
|
||||
$(PROGDIR)/register: $(SRCDIR)/arith.c
|
||||
$(CC) -o $(PROGDIR)/register ${CFLAGS} ${OPTON} -Ddatum='register int' $(SRCDIR)/arith.c
|
||||
$(PROGDIR)/short: $(SRCDIR)/arith.c
|
||||
$(CC) -o $(PROGDIR)/short ${CFLAGS} ${OPTON} -Ddatum=short $(SRCDIR)/arith.c
|
||||
$(PROGDIR)/int: $(SRCDIR)/arith.c
|
||||
$(CC) -o $(PROGDIR)/int ${CFLAGS} ${OPTON} -Ddatum=int $(SRCDIR)/arith.c
|
||||
$(PROGDIR)/long: $(SRCDIR)/arith.c
|
||||
$(CC) -o $(PROGDIR)/long ${CFLAGS} ${OPTON} -Ddatum=long $(SRCDIR)/arith.c
|
||||
$(PROGDIR)/float: $(SRCDIR)/arith.c
|
||||
$(CC) -o $(PROGDIR)/float ${CFLAGS} ${OPTON} -Ddatum=float $(SRCDIR)/arith.c
|
||||
$(PROGDIR)/double: $(SRCDIR)/arith.c
|
||||
$(CC) -o $(PROGDIR)/double ${CFLAGS} ${OPTON} -Ddatum=double $(SRCDIR)/arith.c
|
||||
$(PROGDIR)/whetstone-double: $(SRCDIR)/whets.c
|
||||
$(CC) -o $(PROGDIR)/whetstone-double ${CFLAGS} ${OPTON} -DDP -DUNIX -DUNIXBENCH $(SRCDIR)/whets.c -lm
|
||||
$(PROGDIR)/hanoi: $(SRCDIR)/hanoi.c
|
||||
$(CC) -o $(PROGDIR)/hanoi ${CFLAGS} ${OPTON} $(SRCDIR)/hanoi.c
|
||||
|
||||
$(PROGDIR)/poll: $(SRCDIR)/time-polling.c
|
||||
$(CC) -DHAS_POLL -DUNIXBENCH -o $(PROGDIR)/poll ${CFLAGS} ${OPTON} $(SRCDIR)/time-polling.c
|
||||
|
||||
$(PROGDIR)/poll2: $(SRCDIR)/time-polling.c
|
||||
$(CC) -DHAS_POLL2 -DUNIXBENCH -o $(PROGDIR)/poll2 ${CFLAGS} ${OPTON} $(SRCDIR)/time-polling.c
|
||||
|
||||
$(PROGDIR)/select: $(SRCDIR)/time-polling.c
|
||||
$(CC) -DHAS_SELECT -DUNIXBENCH -o $(PROGDIR)/select ${CFLAGS} ${OPTON} $(SRCDIR)/time-polling.c
|
||||
|
||||
$(PROGDIR)/fstime: $(SRCDIR)/fstime.c
|
||||
$(CC) -o $(PROGDIR)/fstime ${CFLAGS} ${OPTON} $(SRCDIR)/fstime.c
|
||||
|
||||
$(PROGDIR)/syscall: $(SRCDIR)/syscall.c
|
||||
$(CC) -o $(PROGDIR)/syscall ${CFLAGS} ${OPTON} $(SRCDIR)/syscall.c
|
||||
$(PROGDIR)/context1: $(SRCDIR)/context1.c
|
||||
$(CC) -o $(PROGDIR)/context1 ${CFLAGS} ${OPTON} $(SRCDIR)/context1.c
|
||||
$(PROGDIR)/pipe: $(SRCDIR)/pipe.c
|
||||
$(CC) -o $(PROGDIR)/pipe ${CFLAGS} ${OPTON} $(SRCDIR)/pipe.c
|
||||
$(PROGDIR)/spawn: $(SRCDIR)/spawn.c
|
||||
$(CC) -o $(PROGDIR)/spawn ${CFLAGS} ${OPTON} $(SRCDIR)/spawn.c
|
||||
$(PROGDIR)/execl: $(SRCDIR)/execl.c $(SRCDIR)/big.c
|
||||
$(CC) -o $(PROGDIR)/execl ${CFLAGS} ${OPTON} $(SRCDIR)/execl.c
|
||||
|
||||
$(PROGDIR)/dhry2: $(SRCDIR)/dhry_1.c $(SRCDIR)/dhry_2.c $(SRCDIR)/dhry.h
|
||||
cd $(SRCDIR); $(CC) -c ${CFLAGS} -DHZ=${HZ} ${OPTON} dhry_1.c
|
||||
cd $(SRCDIR); $(CC) -c ${CFLAGS} -DHZ=${HZ} ${OPTON} dhry_2.c
|
||||
$(CC) -o $(PROGDIR)/dhry2 ${CFLAGS} ${OPTON} $(SRCDIR)/dhry_1.o $(SRCDIR)/dhry_2.o
|
||||
cd $(SRCDIR); rm -f dhry_1.o dhry_2.o
|
||||
$(PROGDIR)/dhry2reg: $(SRCDIR)/dhry_1.c $(SRCDIR)/dhry_2.c $(SRCDIR)/dhry.h
|
||||
cd $(SRCDIR); $(CC) -c ${CFLAGS} -DREG=register -DHZ=${HZ} ${OPTON} dhry_1.c
|
||||
cd $(SRCDIR); $(CC) -c ${CFLAGS} -DREG=register -DHZ=${HZ} ${OPTON} dhry_2.c
|
||||
$(CC) -o $(PROGDIR)/dhry2reg ${CFLAGS} ${OPTON} $(SRCDIR)/dhry_1.o $(SRCDIR)/dhry_2.o
|
||||
cd $(SRCDIR); rm -f dhry_1.o dhry_2.o
|
||||
|
||||
$(PROGDIR)/looper: $(SRCDIR)/looper.c
|
||||
$(CC) -o $(PROGDIR)/looper ${CFLAGS} ${OPTON} $(SRCDIR)/looper.c
|
||||
|
||||
$(PROGDIR)/ubgears: $(SRCDIR)/ubgears.c
|
||||
$(CC) -o $(PROGDIR)/ubgears ${CFLAGS} ${OPTON} $(SRCDIR)/ubgears.c $(GL_LIBS)
|
||||
|
||||
# Run the benchmarks and create the reports
|
||||
run:
|
||||
sh ./Run
|
||||
|
||||
clean:
|
||||
rm -f $(BINS) core *~ */*~
|
||||
|
||||
spotless: clean
|
||||
rm -f $(RESULTDIR)/* $(TMPDIR)/*
|
||||
|
||||
## END ##
|
406
UnixBench/README
Normal file
406
UnixBench/README
Normal file
@ -0,0 +1,406 @@
|
||||
Version 5.1.2 -- 2007-12-26
|
||||
|
||||
================================================================
|
||||
To use Unixbench:
|
||||
|
||||
1. UnixBench from version 5.1 on has both system and graphics tests.
|
||||
If you want to use the graphic tests, edit the Makefile and make sure
|
||||
that the line "GRAPHIC_TESTS = defined" is not commented out; then check
|
||||
that the "GL_LIBS" definition is OK for your system. Also make sure
|
||||
that the "x11perf" command is on your search path.
|
||||
|
||||
If you don't want the graphics tests, then comment out the
|
||||
"GRAPHIC_TESTS = defined" line. Note: comment it out, don't
|
||||
set it to anything.
|
||||
|
||||
2. Do "make".
|
||||
|
||||
3. Do "Run" to run the system test; "Run graphics" to run the graphics
|
||||
tests; "Run gindex" to run both.
|
||||
|
||||
You will need perl, as Run is written in perl.
|
||||
|
||||
For more information on using the tests, read "USAGE".
|
||||
|
||||
For information on adding tests into the benchmark, see "WRITING_TESTS".
|
||||
|
||||
|
||||
===================== RELEASE NOTES =====================================
|
||||
|
||||
======================== Dec 07 ==========================
|
||||
|
||||
v5.1.2
|
||||
|
||||
One big fix: if unixbench is installed in a directory whose pathname contains
|
||||
a space, it should now run (previously it failed).
|
||||
|
||||
To avoid possible clashes, the environment variables unixbench uses are now
|
||||
prefixed with "UB_". These are all optional, and for most people will be
|
||||
completely unnecessary, but if you want you can set these:
|
||||
|
||||
UB_BINDIR Directory where the test programs live.
|
||||
UB_TMPDIR Temp directory, for temp files.
|
||||
UB_RESULTDIR Directory to put results in.
|
||||
UB_TESTDIR Directory where the tests are executed.
|
||||
|
||||
And a couple of tiny fixes:
|
||||
* In pgms/tst.sh, changed "sort -n +1" to "sort -n -k 1"
|
||||
* In Makefile, made it clearer that GRAPHIC_TESTS should be commented
|
||||
out (not set to 0) to disable graphics
|
||||
Thanks to nordi for pointing these out.
|
||||
|
||||
|
||||
Ian Smith, December 26, 2007
|
||||
johantheghost at yahoo period com
|
||||
|
||||
|
||||
======================== Oct 07 ==========================
|
||||
|
||||
v5.1.1
|
||||
|
||||
It turns out that the setting of LANG is crucial to the results. This
|
||||
explains why people in different regions were seeing odd results, and also
|
||||
why runlevel 1 produced odd results -- runlevel 1 doesn't set LANG, and
|
||||
hence reverts to ASCII, whereas most people use a UTF-8 encoding, which is
|
||||
much slower in some tests (eg. shell tests).
|
||||
|
||||
So now we manually set LANG to "en_US.utf8", which is configured with the
|
||||
variable "$language". Don't change this if you want to share your results.
|
||||
We also report the language settings in use.
|
||||
|
||||
See "The Language Setting" in USAGE for more info. Thanks to nordi for
|
||||
pointing out the LANG issue.
|
||||
|
||||
I also added the "grep" and "sysexec" tests. These are non-index tests,
|
||||
and "grep" uses the system's grep, so it's not much use for comparing
|
||||
different systems. But some folks on the OpenSuSE list have been finding
|
||||
these useful. They aren't in any of the main test groups; do "Run grep
|
||||
sysexec" to run them.
|
||||
|
||||
Index Changes
|
||||
-------------
|
||||
|
||||
The setting of LANG will affect consistency with systems where this is
|
||||
not the default value. However, it should produce more consistent results
|
||||
in future.
|
||||
|
||||
|
||||
Ian Smith, October 15, 2007
|
||||
johantheghost at yahoo period com
|
||||
|
||||
|
||||
======================== Oct 07 ==========================
|
||||
|
||||
v5.1
|
||||
|
||||
The major new feature in this version is the addition of graphical
|
||||
benchmarks. Since these may not compile on all systems, you can enable/
|
||||
disable them with the GRAPHIC_TESTS variable in the Makefile.
|
||||
|
||||
As before, each test is run for 3 or 10 iterations. However, we now discard
|
||||
the worst 1/3 of the scores before averaging the remainder. The logic is
|
||||
that a glitch in the system (background process waking up, for example) may
|
||||
make one or two runs go slow, so let's discard those. Hopefully this will
|
||||
produce more consistent and repeatable results. Check the log file
|
||||
for a test run to see the discarded scores.
|
||||
|
||||
Made the tests compile and run on x86-64/Linux (fixed an execl bug passing
|
||||
int instead of pointer).
|
||||
|
||||
Also fixed some general bugs.
|
||||
|
||||
Thanks to Stefan Esser for help and testing / bug reporting.
|
||||
|
||||
Index Changes
|
||||
-------------
|
||||
|
||||
The tests are now divided into categories, and each category generates
|
||||
its own index. This keeps the graphics test results separate from
|
||||
the system tests.
|
||||
|
||||
The "graphics" test and corresponding index are new.
|
||||
|
||||
The "discard the worst scores" strategy should produce slightly higher
|
||||
test scores, but at least they should (hopefully!) be more consistent.
|
||||
The scores should not be higher than the best scores you would have got
|
||||
with 5.0, so this should not be a huge consistency issue.
|
||||
|
||||
Ian Smith, October 11, 2007
|
||||
johantheghost at yahoo period com
|
||||
|
||||
|
||||
======================== Sep 07 ==========================
|
||||
|
||||
v5.0
|
||||
|
||||
All the work I've done on this release is Linux-based, because that's
|
||||
the only Unix I have access to. I've tried to make it more OS-agnostic
|
||||
if anything; for example, it no longer has to figure out the format reported
|
||||
by /usr/bin/time. However, it's possible that portability has been damaged.
|
||||
If anyone wants to fix this, please feel free to mail me patches.
|
||||
|
||||
In particular, the analysis of the system's CPUs is done via /proc/cpuinfo.
|
||||
For systems which don't have this, please make appropriate changes in
|
||||
getCpuInfo() and getSystemInfo().
|
||||
|
||||
The big change has been to make the tests multi-CPU aware. See the
|
||||
"Multiple CPUs" section in "USAGE" for details. Other changes:
|
||||
|
||||
* Completely rewrote Run in Perl; drastically simplified the way data is
|
||||
processed. The confusing system of interlocking shell and awk scripts is
|
||||
now just one script. Various intermediate files used to store and process
|
||||
results are now replaced by Perl data structures internal to the script.
|
||||
|
||||
* Removed from the index runs file system read and write tests which were
|
||||
ignored for the index and wasted about 10 minutes per run (see fstime.c).
|
||||
The read and write tests can now be selected individually. Made fstime.c
|
||||
take parameters, so we no longer need to build 3 versions of it.
|
||||
|
||||
* Made the output file names unique; they are built from
|
||||
hostname-date-sequence.
|
||||
|
||||
* Worked on result reporting, error handling, and logging. See TESTS.
|
||||
We now generate both text and HTML reports.
|
||||
|
||||
* Removed some obsolete files.
|
||||
|
||||
Index Changes
|
||||
-------------
|
||||
|
||||
The index is still based on David Niemi's SPARCstation 20-61 (rated at 10.0),
|
||||
and the intention in the changes I've made has been to keep the tests
|
||||
unchanged, in order to maintain consistency with old result sets.
|
||||
|
||||
However, the following changes have been made to the index:
|
||||
|
||||
* The Pipe-based Context Switching test (context1) was being dropped
|
||||
from the index report in v4.1.0 due to a bug; I've put it back in.
|
||||
|
||||
* I've added shell1 to the index, to get a measure of how the shell tests
|
||||
scale with multiple CPUs (shell8 already exercises all the CPUs, even
|
||||
in single-copy mode). I made up the baseline score for this by
|
||||
extrapolation.
|
||||
|
||||
Both of these test can be dropped, if you wish, by editing the "TEST
|
||||
SPECIFICATIONS" section of Run.
|
||||
|
||||
Ian Smith, September 20, 2007
|
||||
johantheghost at yahoo period com
|
||||
|
||||
======================== Aug 97 ==========================
|
||||
|
||||
v4.1.0
|
||||
|
||||
Double precision Whetstone put in place instead of the old "double" benchmark.
|
||||
|
||||
Removal of some obsolete files.
|
||||
|
||||
"system" suite adds shell8.
|
||||
|
||||
perlbench and poll added as "exhibition" (non-index) benchmarks.
|
||||
|
||||
Incorporates several suggestions by Andre Derrick Balsa <andrewbalsa@usa.net>
|
||||
|
||||
Code cleanups to reduce compiler warnings by David C Niemi <niemi@tux.org>
|
||||
and Andy Kahn <kahn@zk3.dec.com>; Digital Unix options by Andy Kahn.
|
||||
|
||||
======================== Jun 97 ==========================
|
||||
|
||||
v4.0.1
|
||||
|
||||
Minor change to fstime.c to fix overflow problems on fast machines. Counting
|
||||
is now done in units of 256 (smallest BUFSIZE) and unsigned longs are used,
|
||||
giving another 23 dB or so of headroom ;^) Results should be virtually
|
||||
identical aside from very small rounding errors.
|
||||
|
||||
======================== Dec 95 ==========================
|
||||
|
||||
v4.0
|
||||
|
||||
Byte no longer seems to have anything to do with this benchmark, and I was
|
||||
unable to reach any of the original authors; so I have taken it upon myself
|
||||
to clean it up.
|
||||
|
||||
This is version 4. Major assumptions made in these benchmarks have changed
|
||||
since they were written, but they are nonetheless popular (particularly for
|
||||
measuring hardware for Linux). Some changes made:
|
||||
|
||||
- The biggest change is to put a lot more operating system-oriented
|
||||
tests into the index. I experimented for a while with a decibel-like
|
||||
logarithmic scale, but finally settled on using a geometric mean for
|
||||
the final index (the individual scores are a normalized, and their
|
||||
logs are averaged; the resulting value is exponentiated).
|
||||
|
||||
"George", certain SPARCstation 20-61 with 128 MB RAM, a SPARC Storage
|
||||
Array, and Solaris 2.3 is my new baseline; it is rated at 10.0 in each
|
||||
of the index scores for a final score of 10.0.
|
||||
|
||||
Overall I find the geometric averaging is a big improvement for
|
||||
avoiding the skew that was once possible (e.g. a Pentium-75 which got
|
||||
40 on the buggy version of fstime, such that fstime accounted for over
|
||||
half of its total score and hence wildly skewed its average).
|
||||
|
||||
I also expect that the new numbers look different enough from the old
|
||||
ones that no one is too likely to casually mistake them for each other.
|
||||
|
||||
I am finding new SPARCs running Solaris 2.4 getting about 15-20, and
|
||||
my 486 DX2-66 Compaq running Linux 1.3.45 got a 9.1. It got
|
||||
understandably poor scores on CPU and FPU benchmarks (a horrible
|
||||
1.8 on "double" and 1.3 on "fsdisk"); but made up for it by averaging
|
||||
over 20 on the OS-oriented benchmarks. The Pentium-75 running
|
||||
Linux gets about 20 (and it *still* runs Windows 3.1 slowly. Oh well).
|
||||
|
||||
- It is difficult to get a modern compiler to even consider making
|
||||
dhry2 without registers, short of turning off *all* optimizations.
|
||||
This is also not a terribly meaningful test, even if it were possible,
|
||||
as noone compiles without registers nowadays. Replaced this benchmark
|
||||
with dhry2reg in the index, and dropped it out of usage in general as
|
||||
it is so hard to make a legitimate one.
|
||||
|
||||
- fstime: this had some bugs when compiled on modern systems which return
|
||||
the number of bytes read/written for read(2)/write(2) calls. The code
|
||||
assumed that a negative return code was given for EOF, but most modern
|
||||
systems return 0 (certainly on SunOS 4, Solaris2, and Linux, which is
|
||||
what counts for me). The old code yielded wildly inflated read scores,
|
||||
would eat up tens of MB of disk space on fast systems, and yielded
|
||||
roughly 50% lower than normal copy scores than it should have.
|
||||
|
||||
Also, it counted partial blocks *fully*; made it count the proportional
|
||||
part of the block which was actually finished.
|
||||
|
||||
Made bigger and smaller variants of fstime which are designed to beat
|
||||
up the disk I/O and the buffer cache, respectively. Adjusted the
|
||||
sleeps so that they are short for short benchmarks.
|
||||
|
||||
- Instead of 1,2,4, and 8-shell benchmarks, went to 1, 8, and 16 to
|
||||
give a broader range of information (and to run 1 fewer test).
|
||||
The only real problem with this is that not many iterations get
|
||||
done with 16 at a time on slow systems, so there are some significant
|
||||
rounding errors; 8 therefore still used for the benchmark. There is
|
||||
also the problem that the last (uncompleted) loop is counted as a full
|
||||
loop, so it is impossible to score below 1.0 lpm (which gave my laptop
|
||||
a break). Probably redesigning Shell to do each loop a bit more
|
||||
quickly (but with less intensity) would be a good idea.
|
||||
|
||||
This benchmark appears to be very heavily influenced by the speed
|
||||
of the loader, by which shell is being used as /bin/sh, and by how
|
||||
well-compiled some of the common shell utilities like grep, sed, and
|
||||
sort are. With a consistent tool set it is also a good indicator of
|
||||
the bandwidth between main memory and the CPU (e.g. Pentia score about
|
||||
twice as high as 486es due to their 64-bit bus). Small, sometimes
|
||||
broken shells like "ash-linux" do particularly well here, while big,
|
||||
robust shells like bash do not.
|
||||
|
||||
- "dc" is a somewhat iffy benchmark, because there are two versions of
|
||||
it floating around, one being small, very fast, and buggy, and one
|
||||
being more correct but slow. It was never in the index anyway.
|
||||
|
||||
- Execl is a somewhat troubling benchmark in that it yields much higher
|
||||
scores if compiled statically. I frown on this practice because it
|
||||
distorts the scores away from reflecting how programs are really used
|
||||
(i.e. dynamically linked).
|
||||
|
||||
- Arithoh is really more an indicator of the compiler quality than of
|
||||
the computer itself. For example, GCC 2.7.x with -O2 and a few extra
|
||||
options optimizes much of it away, resulting in about a 1200% boost
|
||||
to the score. Clearly not a good one for the index.
|
||||
|
||||
I am still a bit unhappy with the variance in some of the benchmarks, most
|
||||
notably the fstime suite; and with how long it takes to run. But I think
|
||||
it gets significantly more reliable results than the older version in less
|
||||
time.
|
||||
|
||||
If anyone has ideas on how to make these benchmarks faster, lower-variance,
|
||||
or more meaningful; or has nice, new, portable benchmarks to add, don't
|
||||
hesitate to e-mail me.
|
||||
|
||||
David C Niemi <niemi@tux.org> 7 Dec 1995
|
||||
|
||||
======================== May 91 ==========================
|
||||
This is version 3. This set of programs should be able to determine if
|
||||
your system is BSD or SysV. (It uses the output format of time (1)
|
||||
to see. If you have any problems, contact me (by email,
|
||||
preferably): ben@bytepb.byte.com
|
||||
|
||||
---
|
||||
|
||||
The document doc/bench.doc describes the basic flow of the
|
||||
benchmark system. The document doc/bench3.doc describes the major
|
||||
changes in design of this version. As a user of the benchmarks,
|
||||
you should understand some of the methods that have been
|
||||
implemented to generate loop counts:
|
||||
|
||||
Tests that are compiled C code:
|
||||
The function wake_me(second, func) is included (from the file
|
||||
timeit.c). This function uses signal and alarm to set a countdown
|
||||
for the time request by the benchmark administration script
|
||||
(Run). As soon as the clock is started, the test is run with a
|
||||
counter keeping track of the number of loops that the test makes.
|
||||
When alarm sends its signal, the loop counter value is sent to stderr
|
||||
and the program terminates. Since the time resolution, signal
|
||||
trapping and other factors don't insure that the test is for the
|
||||
precise time that was requested, the test program is also run
|
||||
from the time (1) command. The real time value returned from time
|
||||
(1) is what is used in calculating the number of loops per second
|
||||
(or minute, depending on the test). As is obvious, there is some
|
||||
overhead time that is not taken into account, therefore the
|
||||
number of loops per second is not absolute. The overhead of the
|
||||
test starting and stopping and the signal and alarm calls is
|
||||
common to the overhead of real applications. If a program loads
|
||||
quickly, the number of loops per second increases; a phenomenon
|
||||
that favors systems that can load programs quickly. (Setting the
|
||||
sticky bit of the test programs is not considered fair play.)
|
||||
|
||||
Test that use existing UNIX programs or shell scripts:
|
||||
The concept is the same as that of compiled tests, except the
|
||||
alarm and signal are contained in separate compiled program,
|
||||
looper (source is looper.c). Looper uses an execvp to invoke the
|
||||
test with its arguments. Here, the overhead includes the
|
||||
invocation and execution of looper.
|
||||
|
||||
--
|
||||
|
||||
The index numbers are generated from a baseline file that is in
|
||||
pgms/index.base. You can put tests that you wish in this file.
|
||||
All you need to do is take the results/log file from your
|
||||
baseline machine, edit out the comment and blank lines, and sort
|
||||
the result (vi/ex command: 1,$!sort). The sort in necessary
|
||||
because the process of generating the index report uses join (1).
|
||||
You can regenerate the reports by running "make report."
|
||||
|
||||
--
|
||||
|
||||
========================= Jan 90 =============================
|
||||
Tom Yager has joined the effort here at BYTE; he is responsible
|
||||
for many refinements in the UNIX benchmarks.
|
||||
|
||||
The memory access tests have been deleted from the benchmarks.
|
||||
The file access tests have been reversed so that the test is run
|
||||
for a fixed time. The amount of data transfered (written, read,
|
||||
and copied) is the variable. !WARNING! This test can eat up a
|
||||
large hunk of disk space.
|
||||
|
||||
The initial line of all shell scripts has been changed from the
|
||||
SCO and XENIX form (:) to the more standard form "#! /bin/sh".
|
||||
But different systems handle shell switching differently. Check
|
||||
the documentation on your system and find out how you are
|
||||
supposed to do it. Or, simpler yet, just run the benchmarks from
|
||||
the Bourne shell. (You may need to set SHELL=/bin/sh as well.)
|
||||
|
||||
The options to Run have not been checked in a while. They may no
|
||||
longer function. Next time, I'll get back on them. There needs to
|
||||
be another option added (next time) that halts testing between
|
||||
each test. !WARNING! Some systems have caches that are not getting flushed
|
||||
before the next test or iteration is run. This can cause
|
||||
erroneous values.
|
||||
|
||||
========================= Sept 89 =============================
|
||||
The database (db) programs now have a tuneable message queue space.
|
||||
queue space. The default set in the Run script is 1024 bytes.
|
||||
Other major changes are in the format of the times. We now show
|
||||
Arithmetic and Geometric mean and standard deviation for User
|
||||
Time, System Time, and Real Time. Generally, in reporting, we
|
||||
plan on using the Real Time values with the benchs run with one
|
||||
active user (the bench user). Comments and arguments are requested.
|
||||
|
||||
contact: BIX bensmith or rick_g
|
1835
UnixBench/Run
Executable file
1835
UnixBench/Run
Executable file
File diff suppressed because it is too large
Load Diff
394
UnixBench/USAGE
Normal file
394
UnixBench/USAGE
Normal file
@ -0,0 +1,394 @@
|
||||
Running the Tests
|
||||
=================
|
||||
|
||||
All the tests are executed using the "Run" script in the top-level directory.
|
||||
|
||||
The simplest way to generate results is with the commmand:
|
||||
./Run
|
||||
|
||||
This will run a standard "index" test (see "The BYTE Index" below), and
|
||||
save the report in the "results" directory, with a filename like
|
||||
hostname-2007-09-23-01
|
||||
An HTML version is also saved.
|
||||
|
||||
If you want to generate both the basic system index and the graphics index,
|
||||
then do:
|
||||
./Run gindex
|
||||
|
||||
If your system has more than one CPU, the tests will be run twice -- once
|
||||
with a single copy of each test running at once, and once with N copies,
|
||||
where N is the number of CPUs. Some categories of tests, however (currently
|
||||
the graphics tests) will only run with a single copy.
|
||||
|
||||
Since the tests are based on constant time (variable work), a "system"
|
||||
run usually takes about 29 minutes; the "graphics" part about 18 minutes.
|
||||
A "gindex" run on a dual-core machine will do 2 "system" passes (single-
|
||||
and dual-processing) and one "graphics" run, for a total around one and
|
||||
a quarter hours.
|
||||
|
||||
============================================================================
|
||||
|
||||
Detailed Usage
|
||||
==============
|
||||
|
||||
The Run script takes a number of options which you can use to customise a
|
||||
test, and you can specify the names of the tests to run. The full usage
|
||||
is:
|
||||
|
||||
Run [ -q | -v ] [-i <n> ] [-c <n> [-c <n> ...]] [test ...]
|
||||
|
||||
The option flags are:
|
||||
|
||||
-q Run in quiet mode.
|
||||
-v Run in verbose mode.
|
||||
-i <count> Run <count> iterations for each test -- slower tests
|
||||
use <count> / 3, but at least 1. Defaults to 10 (3 for
|
||||
slow tests).
|
||||
-c <n> Run <n> copies of each test in parallel.
|
||||
|
||||
The -c option can be given multiple times; for example:
|
||||
|
||||
./Run -c 1 -c 4
|
||||
|
||||
will run a single-streamed pass, then a 4-streamed pass. Note that some
|
||||
tests (currently the graphics tests) will only run in a single-streamed pass.
|
||||
|
||||
The remaining non-flag arguments are taken to be the names of tests to run.
|
||||
The default is to run "index". See "Tests" below.
|
||||
|
||||
When running the tests, I do *not* recommend switching to single-user mode
|
||||
("init 1"). This seems to change the results in ways I don't understand,
|
||||
and it's not realistic (unless your system will actually be running in this
|
||||
mode, of course). However, if using a windowing system, you may want to
|
||||
switch to a minimal window setup (for example, log in to a "twm" session),
|
||||
so that randomly-churning background processes don't randomise the results
|
||||
too much. This is particularly true for the graphics tests.
|
||||
|
||||
|
||||
============================================================================
|
||||
|
||||
Tests
|
||||
=====
|
||||
|
||||
The available tests are organised into categories; when generating index
|
||||
scores (see "The BYTE Index" below) the results for each category are
|
||||
produced separately. The categories are:
|
||||
|
||||
system The original Unix system tests (not all are actually
|
||||
in the index)
|
||||
2d 2D graphics tests (not all are actually in the index)
|
||||
3d 3D graphics tests
|
||||
misc Various non-indexed tests
|
||||
|
||||
The following individual tests are available:
|
||||
|
||||
system:
|
||||
dhry2reg Dhrystone 2 using register variables
|
||||
whetstone-double Double-Precision Whetstone
|
||||
syscall System Call Overhead
|
||||
pipe Pipe Throughput
|
||||
context1 Pipe-based Context Switching
|
||||
spawn Process Creation
|
||||
execl Execl Throughput
|
||||
fstime-w File Write 1024 bufsize 2000 maxblocks
|
||||
fstime-r File Read 1024 bufsize 2000 maxblocks
|
||||
fstime File Copy 1024 bufsize 2000 maxblocks
|
||||
fsbuffer-w File Write 256 bufsize 500 maxblocks
|
||||
fsbuffer-r File Read 256 bufsize 500 maxblocks
|
||||
fsbuffer File Copy 256 bufsize 500 maxblocks
|
||||
fsdisk-w File Write 4096 bufsize 8000 maxblocks
|
||||
fsdisk-r File Read 4096 bufsize 8000 maxblocks
|
||||
fsdisk File Copy 4096 bufsize 8000 maxblocks
|
||||
shell1 Shell Scripts (1 concurrent) (runs "looper 60 multi.sh 1")
|
||||
shell8 Shell Scripts (8 concurrent) (runs "looper 60 multi.sh 8")
|
||||
shell16 Shell Scripts (8 concurrent) (runs "looper 60 multi.sh 16")
|
||||
|
||||
2d:
|
||||
2d-rects 2D graphics: rectangles
|
||||
2d-lines 2D graphics: lines
|
||||
2d-circle 2D graphics: circles
|
||||
2d-ellipse 2D graphics: ellipses
|
||||
2d-shapes 2D graphics: polygons
|
||||
2d-aashapes 2D graphics: aa polygons
|
||||
2d-polys 2D graphics: complex polygons
|
||||
2d-text 2D graphics: text
|
||||
2d-blit 2D graphics: images and blits
|
||||
2d-window 2D graphics: windows
|
||||
|
||||
3d:
|
||||
ubgears 3D graphics: gears
|
||||
|
||||
misc:
|
||||
C C Compiler Throughput ("looper 60 $cCompiler cctest.c")
|
||||
arithoh Arithoh (huh?)
|
||||
short Arithmetic Test (short) (this is arith.c configured for
|
||||
"short" variables; ditto for the ones below)
|
||||
int Arithmetic Test (int)
|
||||
long Arithmetic Test (long)
|
||||
float Arithmetic Test (float)
|
||||
double Arithmetic Test (double)
|
||||
dc Dc: sqrt(2) to 99 decimal places (runs
|
||||
"looper 30 dc < dc.dat", using your system's copy of "dc")
|
||||
hanoi Recursion Test -- Tower of Hanoi
|
||||
grep Grep for a string in a large file, using your system's
|
||||
copy of "grep"
|
||||
sysexec Exercise fork() and exec().
|
||||
|
||||
The following pseudo-test names are aliases for combinations of other
|
||||
tests:
|
||||
|
||||
arithmetic Runs arithoh, short, int, long, float, double,
|
||||
and whetstone-double
|
||||
dhry Alias for dhry2reg
|
||||
dhrystone Alias for dhry2reg
|
||||
whets Alias for whetstone-double
|
||||
whetstone Alias for whetstone-double
|
||||
load Runs shell1, shell8, and shell16
|
||||
misc Runs C, dc, and hanoi
|
||||
speed Runs the arithmetic and system groups
|
||||
oldsystem Runs execl, fstime, fsbuffer, fsdisk, pipe, context1,
|
||||
spawn, and syscall
|
||||
system Runs oldsystem plus shell1, shell8, and shell16
|
||||
fs Runs fstime-w, fstime-r, fstime, fsbuffer-w,
|
||||
fsbuffer-r, fsbuffer, fsdisk-w, fsdisk-r, and fsdisk
|
||||
shell Runs shell1, shell8, and shell16
|
||||
|
||||
index Runs the tests which constitute the official index:
|
||||
the oldsystem group, plus dhry2reg, whetstone-double,
|
||||
shell1, and shell8
|
||||
See "The BYTE Index" below for more information.
|
||||
graphics Runs the tests which constitute the graphics index:
|
||||
2d-rects, 2d-ellipse, 2d-aashapes, 2d-text, 2d-blit,
|
||||
2d-window, and ubgears
|
||||
gindex Runs the index and graphics groups, to generate both
|
||||
sets of index results
|
||||
|
||||
all Runs all tests
|
||||
|
||||
|
||||
============================================================================
|
||||
|
||||
The BYTE Index
|
||||
==============
|
||||
|
||||
The purpose of this test is to provide a basic indicator of the performance
|
||||
of a Unix-like system; hence, multiple tests are used to test various
|
||||
aspects of the system's performance. These test results are then compared
|
||||
to the scores from a baseline system to produce an index value, which is
|
||||
generally easier to handle than the raw sores. The entire set of index
|
||||
values is then combined to make an overall index for the system.
|
||||
|
||||
Since 1995, the baseline system has been "George", a SPARCstation 20-61
|
||||
with 128 MB RAM, a SPARC Storage Array, and Solaris 2.3, whose ratings
|
||||
were set at 10.0. (So a system which scores 520 is 52 times faster than
|
||||
this machine.) Since the numbers are really only useful in a relative
|
||||
sense, there's no particular reason to update the base system, so for the
|
||||
sake of consistency it's probably best to leave it alone. George's scores
|
||||
are in the file "pgms/index.base"; this file is used to calculate the
|
||||
index scores for any particular run.
|
||||
|
||||
Over the years, various changes have been made to the set of tests in the
|
||||
index. Although there is a desire for a consistent baseline, various tests
|
||||
have been determined to be misleading, and have been removed; and a few
|
||||
alternatives have been added. These changes are detailed in the README,
|
||||
and should be born in mind when looking at old scores.
|
||||
|
||||
A number of tests are included in the benchmark suite which are not part of
|
||||
the index, for various reasons; these tests can of course be run manually.
|
||||
See "Tests" above.
|
||||
|
||||
|
||||
============================================================================
|
||||
|
||||
Graphics Tests
|
||||
==============
|
||||
|
||||
As of version 5.1, UnixBench now contains some graphics benchmarks. These
|
||||
are intended to give a rough idea of the general graphics performance of
|
||||
a system.
|
||||
|
||||
The graphics tests are in categories "2d" and "3d", so the index scores
|
||||
for these tests are separate from the basic system index. This seems
|
||||
like a sensible division, since the graphics performance of a system
|
||||
depends largely on the graphics adaptor.
|
||||
|
||||
The tests currently consist of some 2D "x11perf" tests and "ubgears".
|
||||
|
||||
* The 2D tests are a selection of the x11perf tests, using the host
|
||||
system's x11perf command (which must be installed and in the search
|
||||
path). Only a few of the x11perf tests are used, in the interests
|
||||
of completing a test run in a reasonable time; if you want to do
|
||||
detailed diagnosis of an X server or graphics chip, then use x11perf
|
||||
directly.
|
||||
|
||||
* The 3D test is "ubgears", a modified version of the familiar "glxgears".
|
||||
This version runs for 5 seconds to "warm up", then performs a timed
|
||||
run and displays the average frames-per-second.
|
||||
|
||||
On multi-CPU systems, the graphics tests will only run in single-processing
|
||||
mode. This is because the meaning of running two copies of a test at once
|
||||
is dubious; and the test windows tend to overlay each other, meaning that
|
||||
the window behind isn't actually doing any work.
|
||||
|
||||
|
||||
============================================================================
|
||||
|
||||
Multiple CPUs
|
||||
=============
|
||||
|
||||
If your system has multiple CPUs, the default behaviour is to run the selected
|
||||
tests twice -- once with one copy of each test program running at a time,
|
||||
and once with N copies, where N is the number of CPUs. (You can override
|
||||
this with the "-c" option; see "Detailed Usage" above.) This is designed to
|
||||
allow you to assess:
|
||||
|
||||
- the performance of your system when running a single task
|
||||
- the performance of your system when running multiple tasks
|
||||
- the gain from your system's implementation of parallel processing
|
||||
|
||||
The results, however, need to be handled with care. Here are the results
|
||||
of two runs on a dual-processor system, one in single-processing mode, one
|
||||
dual-processing:
|
||||
|
||||
Test Single Dual Gain
|
||||
-------------------- ------ ------ ----
|
||||
Dhrystone 2 562.5 1110.3 97%
|
||||
Double Whetstone 320.0 640.4 100%
|
||||
Execl Throughput 450.4 880.3 95%
|
||||
File Copy 1024 759.4 595.9 -22%
|
||||
File Copy 256 535.8 438.8 -18%
|
||||
File Copy 4096 1261.8 1043.4 -17%
|
||||
Pipe Throughput 481.0 979.3 104%
|
||||
Pipe-based Switching 326.8 1229.0 276%
|
||||
Process Creation 917.2 1714.1 87%
|
||||
Shell Scripts (1) 1064.9 1566.3 47%
|
||||
Shell Scripts (8) 1567.7 1709.9 9%
|
||||
System Call Overhead 944.2 1445.5 53%
|
||||
-------------------- ------ ------ ----
|
||||
Index Score: 678.2 1026.2 51%
|
||||
|
||||
As expected, the heavily CPU-dependent tasks -- dhrystone, whetstone,
|
||||
execl, pipe throughput, process creation -- show close to 100% gain when
|
||||
running 2 copies in parallel.
|
||||
|
||||
The Pipe-based Context Switching test measures context switching overhead
|
||||
by sending messages back and forth between 2 processes. I don't know why
|
||||
it shows such a huge gain with 2 copies (ie. 4 processes total) running,
|
||||
but it seems to be consistent on my system. I think this may be an issue
|
||||
with the SMP implementation.
|
||||
|
||||
The System Call Overhead shows a lesser gain, presumably because it uses a
|
||||
lot of CPU time in single-threaded kernel code. The shell scripts test with
|
||||
8 concurrent processes shows no gain -- because the test itself runs 8
|
||||
scripts in parallel, it's already using both CPUs, even when the benchmark
|
||||
is run in single-stream mode. The same test with one process per copy
|
||||
shows a real gain.
|
||||
|
||||
The filesystem throughput tests show a loss, instead of a gain, when
|
||||
multi-processing. That there's no gain is to be expected, since the tests
|
||||
are presumably constrained by the throughput of the I/O subsystem and the
|
||||
disk drive itself; the drop in performance is presumably down to the
|
||||
increased contention for resources, and perhaps greater disk head movement.
|
||||
|
||||
So what tests should you use, how many copies should you run, and how should
|
||||
you interpret the results? Well, that's up to you, since it depends on
|
||||
what it is you're trying to measure.
|
||||
|
||||
Implementation
|
||||
--------------
|
||||
|
||||
The multi-processing mode is implemented at the level of test iterations.
|
||||
During each iteration of a test, N slave processes are started using fork().
|
||||
Each of these slaves executes the test program using fork() and exec(),
|
||||
reads and stores the entire output, times the run, and prints all the
|
||||
results to a pipe. The Run script reads the pipes for each of the slaves
|
||||
in turn to get the results and times. The scores are added, and the times
|
||||
averaged.
|
||||
|
||||
The result is that each test program has N copies running at once. They
|
||||
should all finish at around the same time, since they run for constant time.
|
||||
|
||||
If a test program itself starts off K multiple processes (as with the shell8
|
||||
test), then the effect will be that there are N * K processes running at
|
||||
once. This is probably not very useful for testing multi-CPU performance.
|
||||
|
||||
|
||||
============================================================================
|
||||
|
||||
The Language Setting
|
||||
====================
|
||||
|
||||
The $LANG environment variable determines how programs abnd library
|
||||
routines interpret text. This can have a big impact on the test results.
|
||||
|
||||
If $LANG is set to POSIX, or is left unset, text is treated as ASCII; if
|
||||
it is set to en_US.UTF-8, foir example, then text is treated as being
|
||||
encoded in UTF-8, which is more complex and therefore slower. Setting
|
||||
it to other languages can have varying results.
|
||||
|
||||
To ensure consistency between test runs, the Run script now (as of version
|
||||
5.1.1) sets $LANG to "en_US.utf8".
|
||||
|
||||
This setting which is configured with the variable "$language". You
|
||||
should not change this if you want to share your results to allow
|
||||
comparisons between systems; however, you may want to change it to see
|
||||
how different language settings affect performance.
|
||||
|
||||
Each test report now includes the language settings in use. The reported
|
||||
language is what is set in $LANG, and is not necessarily supported by the
|
||||
system; but we also report the character mapping and collation order which
|
||||
are actually in use (as reported by "locale").
|
||||
|
||||
|
||||
============================================================================
|
||||
|
||||
Interpreting the Results
|
||||
========================
|
||||
|
||||
Interpreting the results of these tests is tricky, and totally depends on
|
||||
what you're trying to measure.
|
||||
|
||||
For example, are you trying to measure how fast your CPU is? Or how good
|
||||
your compiler is? Because these tests are all recompiled using your host
|
||||
system's compiler, the performance of the compiler will inevitably impact
|
||||
the performance of the tests. Is this a problem? If you're choosing a
|
||||
system, you probably care about its overall speed, which may well depend
|
||||
on how good its compiler is; so including that in the test results may be
|
||||
the right answer. But you may want to ensure that the right compiler is
|
||||
used to build the tests.
|
||||
|
||||
On the other hand, with the vast majority of Unix systems being x86 / PC
|
||||
compatibles, running Linux and the GNU C compiler, the results will tend
|
||||
to be more dependent on the hardware; but the versions of the compiler and
|
||||
OS can make a big difference. (I measured a 50% gain between SUSE 10.1
|
||||
and OpenSUSE 10.2 on the same machine.) So you may want to make sure that
|
||||
all your test systems are running the same version of the OS; or at least
|
||||
publish the OS and compuiler versions with your results. Then again, it may
|
||||
be compiler performance that you're interested in.
|
||||
|
||||
The C test is very dubious -- it tests the speed of compilation. If you're
|
||||
running the exact same compiler on each system, OK; but otherwise, the
|
||||
results should probably be discarded. A slower compilation doesn't say
|
||||
anything about the speed of your system, since the compiler may simply be
|
||||
spending more time to super-optimise the code, which would actually make it
|
||||
faster.
|
||||
|
||||
This will be particularly true on architectures like IA-64 (Itanium etc.)
|
||||
where the compiler spends huge amounts of effort scheduling instructions
|
||||
to run in parallel, with a resultant significant gain in execution speed.
|
||||
|
||||
Some tests are even more dubious in terms of host-dependency -- for example,
|
||||
the "dc" test uses the host's version of dc (a calculator program). The
|
||||
version of this which is available can make a huge difference to the score,
|
||||
which is why it's not in the index group. Read through the release notes
|
||||
for more on these kinds of issues.
|
||||
|
||||
Another age-old issue is that of the benchmarks being too trivial to be
|
||||
meaningful. With compilers getting ever smarter, and performing more
|
||||
wide-ranging flow path analyses, the danger of parts of the benchmarks
|
||||
simply being optimised out of existance is always present.
|
||||
|
||||
All in all, the "index" and "gindex" tests (see above) are designed to
|
||||
give a reasonable measure of overall system performance; but the results
|
||||
of any test run should always be used with care.
|
||||
|
133
UnixBench/WRITING_TESTS
Normal file
133
UnixBench/WRITING_TESTS
Normal file
@ -0,0 +1,133 @@
|
||||
Writing a Test
|
||||
==============
|
||||
|
||||
Writing a test program is pretty easy. Basically, a test is configured via
|
||||
a monster array in the Run script, which specifics (among other things) the
|
||||
program to execute and the parameters to pass it.
|
||||
|
||||
The test itself is simply a program which is given the optional parameters
|
||||
on the command line, and produces logging data on stdout and its results on
|
||||
stderr.
|
||||
|
||||
|
||||
============================================================================
|
||||
|
||||
Test Configuration
|
||||
==================
|
||||
|
||||
In Run, all tests are named in the "$testList" array. This names the
|
||||
individual tests, and also sets up aliases for groups of tests, eg. "index".
|
||||
|
||||
The test specifications are in the "$testParams" array. This contains the
|
||||
details of each individual test as a hash. The fields in the hash are:
|
||||
|
||||
* "logmsg": the full name to display for this test.
|
||||
* "cat": the category this test belongs to; must be configured
|
||||
in $testCats.
|
||||
* "prog": the name of the program to execute; defaults to the name of
|
||||
the benchmark.
|
||||
* "repeat": number of passes to run; either 'short' (the default),
|
||||
'long', or 'single'. For 'short' and 'long', the actual numbers of
|
||||
passes are given by $shortIterCount and $longIterCount, which are
|
||||
configured at the top of the script or by the "-i" flag. 'single'
|
||||
means just run one pass; this should be used for test which do their
|
||||
own multi-pass handling internally.
|
||||
* "stdout": non-0 to add the test's stdout to the log file; defaults to 1.
|
||||
Set to 0 for tests that are too wordy.
|
||||
* "stdin": name of a file to send to the program's stdin; default null.
|
||||
* "options": options to be put on the program's command line; default null.
|
||||
|
||||
|
||||
============================================================================
|
||||
|
||||
Output Format
|
||||
=============
|
||||
|
||||
The results on stderr take the form of a line header and fields, separated
|
||||
by "|" characters. A result line can be one of:
|
||||
|
||||
COUNT|score|timebase|label
|
||||
TIME|seconds
|
||||
ERROR|message
|
||||
|
||||
Any other text on stderr is treated as if it were:
|
||||
|
||||
ERROR|text
|
||||
|
||||
Any output to stdout is placed in a log file, and can be used for debugging.
|
||||
|
||||
COUNT
|
||||
-----
|
||||
|
||||
The COUNT line is the line used to report a test score.
|
||||
|
||||
* "score" is the result, typically the number of loops performed during
|
||||
the run
|
||||
* "timebase" is the time base used for the final report to the user. A
|
||||
value of 1 reports the score as is; a value of 60, for example, divides
|
||||
the time taken by 60 to get loops per minute. Atimebase of zero indicates
|
||||
that the score is already a rate, ie. a count of things per second.
|
||||
* "label" is the label to use for the score; like "lps" (loops per
|
||||
second), etc.
|
||||
|
||||
TIME
|
||||
----
|
||||
|
||||
The TIME line is optionally used to report the time taken. The Run script
|
||||
normally measures this, but if your test has signifant overhead outside the
|
||||
actual test loop, you should use TIME to report the time taken for the actual
|
||||
test. The argument is the time in seconds in floating-point.
|
||||
|
||||
ERROR
|
||||
-----
|
||||
|
||||
The argument is an error message; this will abort the benchmarking run and
|
||||
display the message.
|
||||
|
||||
Any output to stderr which is not a formatted line will be treated as an
|
||||
error message, so use of ERROR is optional.
|
||||
|
||||
|
||||
============================================================================
|
||||
|
||||
Test Examples
|
||||
=============
|
||||
|
||||
Iteration Count
|
||||
---------------
|
||||
|
||||
The simplest thing is to count the number of loops executed in a given time;
|
||||
see eg. arith.c. The utlilty functions in timeit.c can be used to implement
|
||||
the fixed time interval, which is generally passed in on the command line.
|
||||
|
||||
The result is reported simply as the number of iterations completed:
|
||||
|
||||
fprintf(stderr,"COUNT|%lu|1|lps\n", iterations);
|
||||
|
||||
The bnenchmark framework will measure the time taken itself. If the test
|
||||
code has significant overhead (eg. a "pump-priming" pass), then you should
|
||||
explicitly report the time taken for the test by adding a line like this:
|
||||
|
||||
fprintf(stderr, "TIME|%.1f\n", seconds);
|
||||
|
||||
If you want results reported as loops per minute, then set timebase to 60:
|
||||
|
||||
fprintf(stderr,"COUNT|%lu|60|lpm\n", iterations);
|
||||
|
||||
Note that this only affects the final report; all times passed to or
|
||||
from the test are still in seconds.
|
||||
|
||||
Rate
|
||||
----
|
||||
|
||||
The other technique is to calculate the rate (things per second) in the test,
|
||||
and report that directly. To do this, just set timebase to 0:
|
||||
|
||||
fprintf(stderr, "COUNT|%ld|0|KBps\n", kbytes_per_sec);
|
||||
|
||||
Again, you can use TIME to explicitly report the time taken:
|
||||
|
||||
fprintf(stderr, "TIME|%.1f\n", end - start);
|
||||
|
||||
but this isn't so important since you've already calculated the rate.
|
||||
|
476
UnixBench/pgms/gfx-x11
Executable file
476
UnixBench/pgms/gfx-x11
Executable file
@ -0,0 +1,476 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
use strict;
|
||||
|
||||
|
||||
############################################################################
|
||||
# gfx-x11: a front-end for x11perf. Runs a selected x11perf test, and
|
||||
# produces output in the format needed by UnixBench.
|
||||
############################################################################
|
||||
# Modification Log:
|
||||
# 2007.09.26 Ian Smith Created
|
||||
############################################################################
|
||||
|
||||
# This program runs sets of x11perf tests, indexes the results against
|
||||
# a common base reference system (see $testData below), and reports the
|
||||
# final score.
|
||||
#
|
||||
# Usage:
|
||||
# gfx-x11 <group> <reps> <time>
|
||||
# where:
|
||||
# <group> is one of the test groups defined in $testGroups below
|
||||
# <reps> is the number of repeats to do per test (the -repeat
|
||||
# argument to x11perf)
|
||||
# <time> is the number of seconds to run each repeat for (the
|
||||
# -time argument to x11perf)
|
||||
# Note that x11perf runs a calibration pass before the requested number
|
||||
# of test passes. The score we compute for a test is the average of the
|
||||
# test passes, divided by the base value in $testData, times 1000.0.
|
||||
# The final score we report is the average of the test scores.
|
||||
|
||||
|
||||
############################################################################
|
||||
# TEST DATA
|
||||
############################################################################
|
||||
|
||||
# This array lists all of the x11perf tests, together with their scores
|
||||
# on an HP Compaq nc8430, with an ATI Mobility Radeon X1600 (256MB)
|
||||
# graphics adapter. There isn't anything special about this reference
|
||||
# system, but scaling all the scores back to a single reference system
|
||||
# allows us to average them in a roughly meaningful way, which in turn
|
||||
# allows us to produce sensible scores for the test groups defined below.
|
||||
#
|
||||
# The results we report are indexed to these values, at a base of 1000.0.
|
||||
my $testData = {
|
||||
'dot' => [ 31700000.0, "Dot" ],
|
||||
'rect1' => [ 18400000.0, "1x1 rectangle" ],
|
||||
'rect10' => [ 7180000.0, "10x10 rectangle" ],
|
||||
'rect100' => [ 110000.0, "100x100 rectangle" ],
|
||||
'rect500' => [ 4110.0, "500x500 rectangle" ],
|
||||
'srect1' => [ 15800000.0, "1x1 stippled rectangle (8x8 stipple)" ],
|
||||
'srect10' => [ 7400000.0, "10x10 stippled rectangle (8x8 stipple)" ],
|
||||
'srect100' => [ 110000.0, "100x100 stippled rectangle (8x8 stipple)" ],
|
||||
'srect500' => [ 4110.0, "500x500 stippled rectangle (8x8 stipple)" ],
|
||||
'osrect1' => [ 15900000.0, "1x1 opaque stippled rectangle (8x8 stipple)" ],
|
||||
'osrect10' => [ 7170000.0, "10x10 opaque stippled rectangle (8x8 stipple)" ],
|
||||
'osrect100' => [ 110000.0, "100x100 opaque stippled rectangle (8x8 stipple)" ],
|
||||
'osrect500' => [ 4110.0, "500x500 opaque stippled rectangle (8x8 stipple)" ],
|
||||
'tilerect1' => [ 15800000.0, "1x1 tiled rectangle (4x4 tile)" ],
|
||||
'tilerect10' => [ 7170000.0, "10x10 tiled rectangle (4x4 tile)" ],
|
||||
'tilerect100' => [ 110000.0, "100x100 tiled rectangle (4x4 tile)" ],
|
||||
'tilerect500' => [ 4110.0, "500x500 tiled rectangle (4x4 tile)" ],
|
||||
'oddsrect1' => [ 2990000.0, "1x1 stippled rectangle (17x15 stipple)" ],
|
||||
'oddsrect10' => [ 1490000.0, "10x10 stippled rectangle (17x15 stipple)" ],
|
||||
'oddsrect100' => [ 55600.0, "100x100 stippled rectangle (17x15 stipple)" ],
|
||||
'oddsrect500' => [ 2360.0, "500x500 stippled rectangle (17x15 stipple)" ],
|
||||
'oddosrect1' => [ 2990000.0, "1x1 opaque stippled rectangle (17x15 stipple)" ],
|
||||
'oddosrect10' => [ 1430000.0, "10x10 opaque stippled rectangle (17x15 stipple)" ],
|
||||
'oddosrect100' => [ 54500.0, "100x100 opaque stippled rectangle (17x15 stipple)" ],
|
||||
'oddosrect500' => [ 2320.0, "500x500 opaque stippled rectangle (17x15 stipple)" ],
|
||||
'oddtilerect1' => [ 2990000.0, "1x1 tiled rectangle (17x15 tile)" ],
|
||||
'oddtilerect10' => [ 1430000.0, "10x10 tiled rectangle (17x15 tile)" ],
|
||||
'oddtilerect100' => [ 54500.0, "100x100 tiled rectangle (17x15 tile)" ],
|
||||
'oddtilerect500' => [ 2320.0, "500x500 tiled rectangle (17x15 tile)" ],
|
||||
'bigsrect1' => [ 4300000.0, "1x1 stippled rectangle (161x145 stipple)" ],
|
||||
'bigsrect10' => [ 705000.0, "10x10 stippled rectangle (161x145 stipple)" ],
|
||||
'bigsrect100' => [ 12300.0, "100x100 stippled rectangle (161x145 stipple)" ],
|
||||
'bigsrect500' => [ 524.0, "500x500 stippled rectangle (161x145 stipple)" ],
|
||||
'bigosrect1' => [ 3980000.0, "1x1 opaque stippled rectangle (161x145 stipple)" ],
|
||||
'bigosrect10' => [ 644000.0, "10x10 opaque stippled rectangle (161x145 stipple)" ],
|
||||
'bigosrect100' => [ 12800.0, "100x100 opaque stippled rectangle (161x145 stipple)" ],
|
||||
'bigosrect500' => [ 584.0, "500x500 opaque stippled rectangle (161x145 stipple)" ],
|
||||
'bigtilerect1' => [ 5970000.0, "1x1 tiled rectangle (161x145 tile)" ],
|
||||
'bigtilerect10' => [ 684000.0, "10x10 tiled rectangle (161x145 tile)" ],
|
||||
'bigtilerect100' => [ 16200.0, "100x100 tiled rectangle (161x145 tile)" ],
|
||||
'bigtilerect500' => [ 872.0, "500x500 tiled rectangle (161x145 tile)" ],
|
||||
'eschertilerect1' => [ 5940000.0, "1x1 tiled rectangle (216x208 tile)" ],
|
||||
'eschertilerect10' => [ 639000.0, "10x10 tiled rectangle (216x208 tile)" ],
|
||||
'eschertilerect100' => [ 18000.0, "100x100 tiled rectangle (216x208 tile)" ],
|
||||
'eschertilerect500' => [ 922.0, "500x500 tiled rectangle (216x208 tile)" ],
|
||||
'seg1' => [ 28800000.0, "1-pixel line segment" ],
|
||||
'seg10' => [ 4460000.0, "10-pixel line segment" ],
|
||||
'seg100' => [ 470000.0, "100-pixel line segment" ],
|
||||
'seg500' => [ 94600.0, "500-pixel line segment" ],
|
||||
'seg100c1' => [ 449000.0, "100-pixel line segment (1 kid)" ],
|
||||
'seg100c2' => [ 432000.0, "100-pixel line segment (2 kids)" ],
|
||||
'seg100c3' => [ 421000.0, "100-pixel line segment (3 kids)" ],
|
||||
'dseg10' => [ 3720000.0, "10-pixel dashed segment" ],
|
||||
'dseg100' => [ 687000.0, "100-pixel dashed segment" ],
|
||||
'ddseg100' => [ 454000.0, "100-pixel double-dashed segment" ],
|
||||
'hseg10' => [ 7020000.0, "10-pixel horizontal line segment" ],
|
||||
'hseg100' => [ 2170000.0, "100-pixel horizontal line segment" ],
|
||||
'hseg500' => [ 456000.0, "500-pixel horizontal line segment" ],
|
||||
'vseg10' => [ 3990000.0, "10-pixel vertical line segment" ],
|
||||
'vseg100' => [ 411000.0, "100-pixel vertical line segment" ],
|
||||
'vseg500' => [ 82400.0, "500-pixel vertical line segment" ],
|
||||
'whseg10' => [ 2880000.0, "10x1 wide horizontal line segment" ],
|
||||
'whseg100' => [ 616000.0, "100x10 wide horizontal line segment" ],
|
||||
'whseg500' => [ 33300.0, "500x50 wide horizontal line segment" ],
|
||||
'wvseg10' => [ 2890000.0, "10x1 wide vertical line segment" ],
|
||||
'wvseg100' => [ 584000.0, "100x10 wide vertical line segment" ],
|
||||
'wvseg500' => [ 31700.0, "500x50 wide vertical line segment" ],
|
||||
'line1' => [ 28300000.0, "1-pixel line" ],
|
||||
'line10' => [ 4470000.0, "10-pixel line" ],
|
||||
'line100' => [ 472000.0, "100-pixel line" ],
|
||||
'line500' => [ 94200.0, "500-pixel line" ],
|
||||
'dline10' => [ 3640000.0, "10-pixel dashed line" ],
|
||||
'dline100' => [ 673000.0, "100-pixel dashed line" ],
|
||||
'ddline100' => [ 453000.0, "100-pixel double-dashed line" ],
|
||||
'wline10' => [ 908000.0, "10x1 wide line" ],
|
||||
'wline100' => [ 146000.0, "100x10 wide line" ],
|
||||
'wline500' => [ 30600.0, "500x50 wide line" ],
|
||||
'wdline100' => [ 69900.0, "100x10 wide dashed line" ],
|
||||
'wddline100' => [ 60600.0, "100x10 wide double-dashed line" ],
|
||||
'orect10' => [ 5100000.0, "10x10 rectangle outline" ],
|
||||
'orect100' => [ 709000.0, "100x100 rectangle outline" ],
|
||||
'orect500' => [ 146000.0, "500x500 rectangle outline" ],
|
||||
'worect10' => [ 4530000.0, "10x10 wide rectangle outline" ],
|
||||
'worect100' => [ 204000.0, "100x100 wide rectangle outline" ],
|
||||
'worect500' => [ 9790.0, "500x500 wide rectangle outline" ],
|
||||
'circle1' => [ 5160000.0, "1-pixel circle" ],
|
||||
'circle10' => [ 1160000.0, "10-pixel circle" ],
|
||||
'circle100' => [ 141000.0, "100-pixel circle" ],
|
||||
'circle500' => [ 28900.0, "500-pixel circle" ],
|
||||
'dcircle100' => [ 98400.0, "100-pixel dashed circle" ],
|
||||
'ddcircle100' => [ 75000.0, "100-pixel double-dashed circle" ],
|
||||
'wcircle10' => [ 780000.0, "10-pixel wide circle" ],
|
||||
'wcircle100' => [ 90900.0, "100-pixel wide circle" ],
|
||||
'wcircle500' => [ 11300.0, "500-pixel wide circle" ],
|
||||
'wdcircle100' => [ 8100.0, "100-pixel wide dashed circle" ],
|
||||
'wddcircle100' => [ 8300.0, "100-pixel wide double-dashed circle" ],
|
||||
'pcircle10' => [ 1270000.0, "10-pixel partial circle" ],
|
||||
'pcircle100' => [ 212000.0, "100-pixel partial circle" ],
|
||||
'wpcircle10' => [ 104000.0, "10-pixel wide partial circle" ],
|
||||
'wpcircle100' => [ 39000.0, "100-pixel wide partial circle" ],
|
||||
'fcircle1' => [ 61300000.0, "1-pixel solid circle" ],
|
||||
'fcircle10' => [ 1720000.0, "10-pixel solid circle" ],
|
||||
'fcircle100' => [ 120000.0, "100-pixel solid circle" ],
|
||||
'fcircle500' => [ 5170.0, "500-pixel solid circle" ],
|
||||
'fcpcircle10' => [ 981000.0, "10-pixel fill chord partial circle" ],
|
||||
'fcpcircle100' => [ 205000.0, "100-pixel fill chord partial circle" ],
|
||||
'fspcircle10' => [ 876000.0, "10-pixel fill slice partial circle" ],
|
||||
'fspcircle100' => [ 187000.0, "100-pixel fill slice partial circle" ],
|
||||
'ellipse10' => [ 1410000.0, "10-pixel ellipse" ],
|
||||
'ellipse100' => [ 172000.0, "100-pixel ellipse" ],
|
||||
'ellipse500' => [ 35100.0, "500-pixel ellipse" ],
|
||||
'dellipse100' => [ 114000.0, "100-pixel dashed ellipse" ],
|
||||
'ddellipse100' => [ 88900.0, "100-pixel double-dashed ellipse" ],
|
||||
'wellipse10' => [ 889000.0, "10-pixel wide ellipse" ],
|
||||
'wellipse100' => [ 124000.0, "100-pixel wide ellipse" ],
|
||||
'wellipse500' => [ 15600.0, "500-pixel wide ellipse" ],
|
||||
'wdellipse100' => [ 7730.0, "100-pixel wide dashed ellipse" ],
|
||||
'wddellipse100' => [ 6680.0, "100-pixel wide double-dashed ellipse" ],
|
||||
'pellipse10' => [ 1350000.0, "10-pixel partial ellipse" ],
|
||||
'pellipse100' => [ 260000.0, "100-pixel partial ellipse" ],
|
||||
'wpellipse10' => [ 97900.0, "10-pixel wide partial ellipse" ],
|
||||
'wpellipse100' => [ 16800.0, "100-pixel wide partial ellipse" ],
|
||||
'fellipse10' => [ 2110000.0, "10-pixel filled ellipse" ],
|
||||
'fellipse100' => [ 212000.0, "100-pixel filled ellipse" ],
|
||||
'fellipse500' => [ 11000.0, "500-pixel filled ellipse" ],
|
||||
'fcpellipse10' => [ 1060000.0, "10-pixel fill chord partial ellipse" ],
|
||||
'fcpellipse100' => [ 296000.0, "100-pixel fill chord partial ellipse" ],
|
||||
'fspellipse10' => [ 945000.0, "10-pixel fill slice partial ellipse" ],
|
||||
'fspellipse100' => [ 269000.0, "100-pixel fill slice partial ellipse" ],
|
||||
'triangle1' => [ 2460000.0, "Fill 1x1 equivalent triangle" ],
|
||||
'triangle10' => [ 969000.0, "Fill 10x10 equivalent triangle" ],
|
||||
'triangle100' => [ 97000.0, "Fill 100x100 equivalent triangle" ],
|
||||
'trap1' => [ 2630000.0, "Fill 1x1 trapezoid" ],
|
||||
'trap10' => [ 1260000.0, "Fill 10x10 trapezoid" ],
|
||||
'trap100' => [ 106000.0, "Fill 100x100 trapezoid" ],
|
||||
'trap300' => [ 11600.0, "Fill 300x300 trapezoid" ],
|
||||
'strap1' => [ 2010000.0, "Fill 1x1 stippled trapezoid (8x8 stipple)" ],
|
||||
'strap10' => [ 910000.0, "Fill 10x10 stippled trapezoid (8x8 stipple)" ],
|
||||
'strap100' => [ 104000.0, "Fill 100x100 stippled trapezoid (8x8 stipple)" ],
|
||||
'strap300' => [ 11700.0, "Fill 300x300 stippled trapezoid (8x8 stipple)" ],
|
||||
'ostrap1' => [ 2000000.0, "Fill 1x1 opaque stippled trapezoid (8x8 stipple)" ],
|
||||
'ostrap10' => [ 907000.0, "Fill 10x10 opaque stippled trapezoid (8x8 stipple)" ],
|
||||
'ostrap100' => [ 104000.0, "Fill 100x100 opaque stippled trapezoid (8x8 stipple)" ],
|
||||
'ostrap300' => [ 11600.0, "Fill 300x300 opaque stippled trapezoid (8x8 stipple)" ],
|
||||
'tiletrap1' => [ 1430000.0, "Fill 1x1 tiled trapezoid (4x4 tile)" ],
|
||||
'tiletrap10' => [ 778000.0, "Fill 10x10 tiled trapezoid (4x4 tile)" ],
|
||||
'tiletrap100' => [ 104000.0, "Fill 100x100 tiled trapezoid (4x4 tile)" ],
|
||||
'tiletrap300' => [ 11600.0, "Fill 300x300 tiled trapezoid (4x4 tile)" ],
|
||||
'oddstrap1' => [ 1700000.0, "Fill 1x1 stippled trapezoid (17x15 stipple)" ],
|
||||
'oddstrap10' => [ 296000.0, "Fill 10x10 stippled trapezoid (17x15 stipple)" ],
|
||||
'oddstrap100' => [ 18600.0, "Fill 100x100 stippled trapezoid (17x15 stipple)" ],
|
||||
'oddstrap300' => [ 2090.0, "Fill 300x300 stippled trapezoid (17x15 stipple)" ],
|
||||
'oddostrap1' => [ 1830000.0, "Fill 1x1 opaque stippled trapezoid (17x15 stipple)" ],
|
||||
'oddostrap10' => [ 296000.0, "Fill 10x10 opaque stippled trapezoid (17x15 stipple)" ],
|
||||
'oddostrap100' => [ 18400.0, "Fill 100x100 opaque stippled trapezoid (17x15 stipple)" ],
|
||||
'oddostrap300' => [ 2080.0, "Fill 300x300 opaque stippled trapezoid (17x15 stipple)" ],
|
||||
'oddtiletrap1' => [ 1710000.0, "Fill 1x1 tiled trapezoid (17x15 tile)" ],
|
||||
'oddtiletrap10' => [ 296000.0, "Fill 10x10 tiled trapezoid (17x15 tile)" ],
|
||||
'oddtiletrap100' => [ 18400.0, "Fill 100x100 tiled trapezoid (17x15 tile)" ],
|
||||
'oddtiletrap300' => [ 2080.0, "Fill 300x300 tiled trapezoid (17x15 tile)" ],
|
||||
'bigstrap1' => [ 1510000.0, "Fill 1x1 stippled trapezoid (161x145 stipple)" ],
|
||||
'bigstrap10' => [ 235000.0, "Fill 10x10 stippled trapezoid (161x145 stipple)" ],
|
||||
'bigstrap100' => [ 9110.0, "Fill 100x100 stippled trapezoid (161x145 stipple)" ],
|
||||
'bigstrap300' => [ 1260.0, "Fill 300x300 stippled trapezoid (161x145 stipple)" ],
|
||||
'bigostrap1' => [ 1480000.0, "Fill 1x1 opaque stippled trapezoid (161x145 stipple)" ],
|
||||
'bigostrap10' => [ 213000.0, "Fill 10x10 opaque stippled trapezoid (161x145 stipple)" ],
|
||||
'bigostrap100' => [ 8830.0, "Fill 100x100 opaque stippled trapezoid (161x145 stipple)" ],
|
||||
'bigostrap300' => [ 1420.0, "Fill 300x300 opaque stippled trapezoid (161x145 stipple)" ],
|
||||
'bigtiletrap1' => [ 1630000.0, "Fill 1x1 tiled trapezoid (161x145 tile)" ],
|
||||
'bigtiletrap10' => [ 272000.0, "Fill 10x10 tiled trapezoid (161x145 tile)" ],
|
||||
'bigtiletrap100' => [ 12900.0, "Fill 100x100 tiled trapezoid (161x145 tile)" ],
|
||||
'bigtiletrap300' => [ 2350.0, "Fill 300x300 tiled trapezoid (161x145 tile)" ],
|
||||
'eschertiletrap1' => [ 1650000.0, "Fill 1x1 tiled trapezoid (216x208 tile)" ],
|
||||
'eschertiletrap10' => [ 273000.0, "Fill 10x10 tiled trapezoid (216x208 tile)" ],
|
||||
'eschertiletrap100' => [ 13400.0, "Fill 100x100 tiled trapezoid (216x208 tile)" ],
|
||||
'eschertiletrap300' => [ 2450.0, "Fill 300x300 tiled trapezoid (216x208 tile)" ],
|
||||
'aatrap1' => [ 260000.0, "Fill 1x1 aa trap" ],
|
||||
'aatrap10' => [ 23500.0, "Fill 10x10 aa trap" ],
|
||||
'aatrap100' => [ 13300.0, "Fill 100x100 aa trap" ],
|
||||
'aatrap300' => [ 4450.0, "Fill 300x300 aa trap" ],
|
||||
'aa4trap1' => [ 2150.0, "Fill 1x1 aa trap with 4 bit alpha" ],
|
||||
'aa4trap10' => [ 2130.0, "Fill 10x10 aa trap with 4 bit alpha" ],
|
||||
'aa4trap100' => [ 1890.0, "Fill 100x100 aa trap with 4 bit alpha" ],
|
||||
'aa4trap300' => [ 1460.0, "Fill 300x300 aa trap with 4 bit alpha" ],
|
||||
'aa1trap1' => [ 2200000.0, "Fill 1x1 aa trap with 1 bit alpha" ],
|
||||
'aa1trap10' => [ 357000.0, "Fill 10x10 aa trap with 1 bit alpha" ],
|
||||
'aa1trap100' => [ 167000.0, "Fill 100x100 aa trap with 1 bit alpha" ],
|
||||
'aa1trap300' => [ 67000.0, "Fill 300x300 aa trap with 1 bit alpha" ],
|
||||
'aatrap2x1' => [ 368000.0, "Fill 2x1 aa trap" ],
|
||||
'aatrap2x10' => [ 25700.0, "Fill 2x10 aa trap" ],
|
||||
'aatrap2x100' => [ 12400.0, "Fill 2x100 aa trap" ],
|
||||
'aatrap2x300' => [ 5710.0, "Fill 2x300 aa trap" ],
|
||||
'aatrapezoid1' => [ 372000.0, "Fill 1x1 aa trapezoid" ],
|
||||
'aatrapezoid10' => [ 137000.0, "Fill 10x10 aa trapezoid" ],
|
||||
'aatrapezoid100' => [ 9590.0, "Fill 100x100 aa trapezoid" ],
|
||||
'aatrapezoid300' => [ 1420.0, "Fill 300x300 aa trapezoid" ],
|
||||
'addaatrapezoid1' => [ 433000.0, "Fill 1x1 aa pre-added trapezoid" ],
|
||||
'addaatrapezoid10' => [ 24100.0, "Fill 10x10 aa pre-added trapezoid" ],
|
||||
'addaatrapezoid100' => [ 13300.0, "Fill 100x100 aa pre-added trapezoid" ],
|
||||
'addaatrapezoid300' => [ 4460.0, "Fill 300x300 aa pre-added trapezoid" ],
|
||||
'complex10' => [ 655000.0, "Fill 10x10 equivalent complex polygon" ],
|
||||
'complex100' => [ 87000.0, "Fill 100x100 equivalent complex polygons" ],
|
||||
'64poly10convex' => [ 481000.0, "Fill 10x10 64-gon (Convex)" ],
|
||||
'64poly100convex' => [ 105000.0, "Fill 100x100 64-gon (Convex)" ],
|
||||
'64poly10complex' => [ 353000.0, "Fill 10x10 64-gon (Complex)" ],
|
||||
'64poly100complex' => [ 105000.0, "Fill 100x100 64-gon (Complex)" ],
|
||||
'ftext' => [ 2200000.0, "Char in 80-char line (6x13)" ],
|
||||
'f8text' => [ 1970000.0, "Char in 70-char line (8x13)" ],
|
||||
'f9text' => [ 1690000.0, "Char in 60-char line (9x15)" ],
|
||||
'f14text16' => [ 679000.0, "Char16 in 40-char line (k14)" ],
|
||||
'f24text16' => [ 272000.0, "Char16 in 23-char line (k24)" ],
|
||||
'tr10text' => [ 2520000.0, "Char in 80-char line (TR 10)" ],
|
||||
'tr24text' => [ 940000.0, "Char in 30-char line (TR 24)" ],
|
||||
'polytext' => [ 2230000.0, "Char in 20/40/20 line (6x13, TR 10)" ],
|
||||
'polytext16' => [ 369000.0, "Char16 in 7/14/7 line (k14, k24)" ],
|
||||
'fitext' => [ 1350000.0, "Char in 80-char image line (6x13)" ],
|
||||
'f8itext' => [ 1130000.0, "Char in 70-char image line (8x13)" ],
|
||||
'f9itext' => [ 902000.0, "Char in 60-char image line (9x15)" ],
|
||||
'f14itext16' => [ 449000.0, "Char16 in 40-char image line (k14)" ],
|
||||
'f24itext16' => [ 169000.0, "Char16 in 23-char image line (k24)" ],
|
||||
'tr10itext' => [ 1590000.0, "Char in 80-char image line (TR 10)" ],
|
||||
'tr24itext' => [ 435000.0, "Char in 30-char image line (TR 24)" ],
|
||||
'aa10text' => [ 53200.0, "Char in 80-char aa line (Charter 10)" ],
|
||||
'aa24text' => [ 13300.0, "Char in 30-char aa line (Charter 24)" ],
|
||||
'aaftext' => [ 45200.0, "Char in 80-char aa line (Courier 12)" ],
|
||||
'a10text' => [ 53100.0, "Char in 80-char a line (Charter 10)" ],
|
||||
'a24text' => [ 13300.0, "Char in 30-char a line (Charter 24)" ],
|
||||
'aftext' => [ 45200.0, "Char in 80-char a line (Courier 12)" ],
|
||||
'rgb10text' => [ 49400.0, "Char in 80-char rgb line (Charter 10)" ],
|
||||
'rgb24text' => [ 10200.0, "Char in 30-char rgb line (Charter 24)" ],
|
||||
'rgbftext' => [ 42200.0, "Char in 80-char rgb line (Courier 12)" ],
|
||||
'caa10text' => [ 15300.0, "Char in 80-char aa core line (Charter 10)" ],
|
||||
'caa24text' => [ 2540.0, "Char in 30-char aa core line (Charter 24)" ],
|
||||
'caaftext' => [ 10900.0, "Char in 80-char aa core line (Courier 12)" ],
|
||||
'ca10text' => [ 15300.0, "Char in 80-char a core line (Charter 10)" ],
|
||||
'ca24text' => [ 2540.0, "Char in 30-char a core line (Charter 24)" ],
|
||||
'caftext' => [ 10900.0, "Char in 80-char a core line (Courier 12)" ],
|
||||
'rgb10text' => [ 15000.0, "Char in 80-char rgb core line (Charter 10)" ],
|
||||
'rgb24text' => [ 2510.0, "Char in 30-char rgb core line (Charter 24)" ],
|
||||
'rgbftext' => [ 10700.0, "Char in 80-char rgb core line (Courier 12)" ],
|
||||
'scroll10' => [ 1310000.0, "Scroll 10x10 pixels" ],
|
||||
'scroll100' => [ 52000.0, "Scroll 100x100 pixels" ],
|
||||
'scroll500' => [ 2190.0, "Scroll 500x500 pixels" ],
|
||||
'copywinwin10' => [ 1030000.0, "Copy 10x10 from window to window" ],
|
||||
'copywinwin100' => [ 52200.0, "Copy 100x100 from window to window" ],
|
||||
'copywinwin500' => [ 2080.0, "Copy 500x500 from window to window" ],
|
||||
'copypixwin10' => [ 502000.0, "Copy 10x10 from pixmap to window" ],
|
||||
'copypixwin100' => [ 20300.0, "Copy 100x100 from pixmap to window" ],
|
||||
'copypixwin500' => [ 1020.0, "Copy 500x500 from pixmap to window" ],
|
||||
'copywinpix10' => [ 7730.0, "Copy 10x10 from window to pixmap" ],
|
||||
'copywinpix100' => [ 127.0, "Copy 100x100 from window to pixmap" ],
|
||||
'copywinpix500' => [ 5.0, "Copy 500x500 from window to pixmap" ],
|
||||
'copypixpix10' => [ 1260000.0, "Copy 10x10 from pixmap to pixmap" ],
|
||||
'copypixpix100' => [ 56300.0, "Copy 100x100 from pixmap to pixmap" ],
|
||||
'copypixpix500' => [ 2470.0, "Copy 500x500 from pixmap to pixmap" ],
|
||||
'copyplane10' => [ 466000.0, "Copy 10x10 1-bit deep plane" ],
|
||||
'copyplane100' => [ 13700.0, "Copy 100x100 1-bit deep plane" ],
|
||||
'copyplane500' => [ 671.0, "Copy 500x500 1-bit deep plane" ],
|
||||
'deepcopyplane10' => [ 151000.0, "Copy 10x10 n-bit deep plane" ],
|
||||
'deepcopyplane100' => [ 6090.0, "Copy 100x100 n-bit deep plane" ],
|
||||
'deepcopyplane500' => [ 278.0, "Copy 500x500 n-bit deep plane" ],
|
||||
'putimage10' => [ 434000.0, "PutImage 10x10 square" ],
|
||||
'putimage100' => [ 13600.0, "PutImage 100x100 square" ],
|
||||
'putimage500' => [ 713.0, "PutImage 500x500 square" ],
|
||||
'putimagexy10' => [ 321.0, "PutImage XY 10x10 square" ],
|
||||
'putimagexy100' => [ 3.2, "PutImage XY 100x100 square" ],
|
||||
'putimagexy500' => [ 0.1, "PutImage XY 500x500 square" ],
|
||||
'shmput10' => [ 465000.0, "ShmPutImage 10x10 square" ],
|
||||
'shmput100' => [ 20200.0, "ShmPutImage 100x100 square" ],
|
||||
'shmput500' => [ 1020.0, "ShmPutImage 500x500 square" ],
|
||||
'shmputxy10' => [ 31400.0, "ShmPutImage XY 10x10 square" ],
|
||||
'shmputxy100' => [ 458.0, "ShmPutImage XY 100x100 square" ],
|
||||
'shmputxy500' => [ 19.0, "ShmPutImage XY 500x500 square" ],
|
||||
'getimage10' => [ 6650.0, "GetImage 10x10 square" ],
|
||||
'getimage100' => [ 77.0, "GetImage 100x100 square" ],
|
||||
'getimage500' => [ 3.1, "GetImage 500x500 square" ],
|
||||
'getimagexy10' => [ 320.0, "GetImage XY 10x10 square" ],
|
||||
'getimagexy100' => [ 3.2, "GetImage XY 100x100 square" ],
|
||||
'getimagexy500' => [ 0.1, "GetImage XY 500x500 square" ],
|
||||
'noop' => [ 8760000.0, "X protocol NoOperation" ],
|
||||
'pointer' => [ 54800.0, "QueryPointer" ],
|
||||
'prop' => [ 50900.0, "GetProperty" ],
|
||||
'gc' => [ 1190000.0, "Change graphics context" ],
|
||||
'create' => [ 597000.0, "Create and map subwindows (25 kids)" ],
|
||||
'ucreate' => [ 1100000.0, "Create unmapped window (25 kids)" ],
|
||||
'map' => [ 1350000.0, "Map window via parent (25 kids)" ],
|
||||
'unmap' => [ 3360000.0, "Unmap window via parent (25 kids)" ],
|
||||
'destroy' => [ 1190000.0, "Destroy window via parent (25 kids)" ],
|
||||
'popup' => [ 660000.0, "Hide/expose window via popup (25 kids)" ],
|
||||
'move' => [ 120000.0, "Move window (25 kids)" ],
|
||||
'umove' => [ 1990000.0, "Moved unmapped window (25 kids)" ],
|
||||
'movetree' => [ 877000.0, "Move window via parent (25 kids)" ],
|
||||
'resize' => [ 136000.0, "Resize window (25 kids)" ],
|
||||
'uresize' => [ 1870000.0, "Resize unmapped window (25 kids)" ],
|
||||
'circulate' => [ 56300.0, "Circulate window (25 kids)" ],
|
||||
'ucirculate' => [ 3630000.0, "Circulate Unmapped window (25 kids)" ],
|
||||
};
|
||||
|
||||
|
||||
# This array defines named groups of tests. This is designed to allow
|
||||
# for simpler runs of related tests.
|
||||
#
|
||||
# Note that this array does *not* include all the x11perf tests. The idea
|
||||
# here is to run a representative sampling of the available tests, to get
|
||||
# a general idea of a system's performance, without taking forever to
|
||||
# do it. If you want to do detailed analysis of an X server or graphics
|
||||
# chip, then use x11perf directly.
|
||||
my $testGroups = {
|
||||
'rects' => [ "rect10", "rect100", "oddtilerect10", "eschertilerect100" ],
|
||||
'lines' => [ "seg100c3", "wvseg100", "ddline100", "worect500" ],
|
||||
'circle' => [ "circle500", "wddcircle100", "wpcircle100", "fspcircle100" ],
|
||||
'ellipse' => [ "ddellipse100", "wddellipse100", "pellipse10", "fspellipse100" ],
|
||||
'shapes' => [ "triangle10", "trap300", "oddostrap300", "eschertiletrap300" ],
|
||||
'aashapes' => [ "aa4trap300", "aa1trap10", "aatrap2x300", "addaatrapezoid300" ],
|
||||
'polys' => [ "complex10", "64poly100convex", "64poly10complex", "64poly100complex" ],
|
||||
'text' => [ "polytext16", "rgb24text", "caa10text", "ca24text" ],
|
||||
'blit' => [ "scroll100", "copypixwin10", "deepcopyplane10", "putimagexy500" ],
|
||||
'window' => [ "popup", "move", "movetree", "resize" ],
|
||||
};
|
||||
|
||||
|
||||
############################################################################
|
||||
# CODE
|
||||
############################################################################
|
||||
|
||||
# Exec the given command, and catch its standard output.
|
||||
# We return an array containing the PID and the filehandle on the
|
||||
# process' standard output. It's up to the caller to wait for the command
|
||||
# to terminate.
|
||||
sub command {
|
||||
my ( $cmd ) = @_;
|
||||
|
||||
my $pid = open(my $childFd, "-|");
|
||||
if (!defined($pid)) {
|
||||
die("Run: fork() failed (undef)\n");
|
||||
} elsif ($pid == 0) {
|
||||
exec($cmd);
|
||||
die("Run: exec() failed (returned)\n");
|
||||
}
|
||||
|
||||
return ( $pid, $childFd );
|
||||
}
|
||||
|
||||
|
||||
# Get data from running a system command. Used for things like getting
|
||||
# the host OS from `uname -o` etc.
|
||||
#
|
||||
# Ignores initial blank lines from the command and returns the first
|
||||
# non-blank line, with white space trimmed off.
|
||||
sub runTest {
|
||||
my ( $test, $reps, $time ) = @_;
|
||||
|
||||
my $tdata = $testData->{$test};
|
||||
if (!defined($tdata)) {
|
||||
printf STDERR "gfx-x11: No such test: %s\n", $test;
|
||||
exit(9);
|
||||
}
|
||||
|
||||
my $cmd = sprintf "x11perf -repeat %d -subs 25 -time %d -%s",
|
||||
$reps, $time, $test;
|
||||
my ( $pid, $fd ) = command($cmd);
|
||||
my $average = 0;
|
||||
while (<$fd>) {
|
||||
chomp;
|
||||
|
||||
# Display the output for logging.
|
||||
printf "%s\n", $_;
|
||||
|
||||
# Save the score.
|
||||
my ( $reps, $per, $rate ) =
|
||||
( m:([0-9]+)\s+trep\s+@\s+([0-9.]+)\s+msec\s+\(\s*([0-9.]+)/sec\): );
|
||||
$average = $rate if (defined($rate));
|
||||
}
|
||||
|
||||
# Close the command and wait for it to die. Bomb out if it failed.
|
||||
# close($fd);
|
||||
my $p = waitpid($pid, 0);
|
||||
my $status = $?;
|
||||
exit($status) if ($status != 0);
|
||||
|
||||
# Calculate and return the weighted result.
|
||||
my $score = $average / $tdata->[0] * 1000.0;
|
||||
printf "Test %s: %d --> %.1f\n", $test, $average, $score;
|
||||
return $score;
|
||||
}
|
||||
|
||||
|
||||
sub runGroup {
|
||||
my ( $group, $reps, $time ) = @_;
|
||||
|
||||
my $gdata = $testGroups->{$group};
|
||||
if (!defined($gdata)) {
|
||||
printf STDERR "gfx-x11: No such test group: %s\n", $group;
|
||||
exit(9);
|
||||
}
|
||||
|
||||
my $count = 0;
|
||||
my $total = 0;
|
||||
foreach my $test (@$gdata) {
|
||||
$total += runTest($test, $reps, $time);
|
||||
++$count;
|
||||
}
|
||||
$total /= $count;
|
||||
|
||||
$total;
|
||||
}
|
||||
|
||||
|
||||
############################################################################
|
||||
# MAIN
|
||||
############################################################################
|
||||
|
||||
sub main {
|
||||
my @args = @_;
|
||||
|
||||
if (scalar(@args) < 3) {
|
||||
printf STDERR "Usage: gfx-x11 group reps time\n";
|
||||
exit(9);
|
||||
}
|
||||
|
||||
my $reps = $args[1];
|
||||
my $time = $args[2];
|
||||
|
||||
my $score = runGroup($args[0], $reps, $time);
|
||||
printf STDERR "COUNT|%.1f|0|score\n", $score;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
exit(main(@ARGV));
|
||||
|
46
UnixBench/pgms/index.base
Normal file
46
UnixBench/pgms/index.base
Normal file
@ -0,0 +1,46 @@
|
||||
# Baseline benchmark scores, used for calculating index results.
|
||||
|
||||
# Scores from "George", a SPARCstation 20-61.
|
||||
dhry2reg|10|lps|116700|116700|2
|
||||
whetstone-double|10|MWIPS|55.0|55.0|2
|
||||
execl|20|lps|43.0|43.0|1
|
||||
fstime|20|KBps|3960|3960|1
|
||||
fsbuffer|20|KBps|1655|1655|1
|
||||
fsdisk|20|KBps|5800|5800|1
|
||||
pipe|10|lps|12440|12440|2
|
||||
context1|10|lps|4000|4000|2
|
||||
spawn|20|lps|126|126|1
|
||||
shell8|60|lpm|6|6|1
|
||||
syscall|10|lps|15000|15000|2
|
||||
|
||||
# The shell1 test was added to the index in 5.0, and this baseline score
|
||||
# was extrapolated to roughly match George's performance.
|
||||
shell1|60|lpm|42.4|42.4|1
|
||||
|
||||
# The 2D baseline scores were derived from a test run on an HP Compaq nc8430
|
||||
# with an ATI Mobility Radeon X1600 Video (256MB) — this is a fairly
|
||||
# common modern adaptor with 3D. The baseline scores here are then
|
||||
# 1/66.6 of the values from that run, to bring them roughly in line with
|
||||
# George. (The HP has an index score of 666.6 single-process.)
|
||||
2d-rects|3|score|15|15|1
|
||||
#2d-lines|3|score|15|15|1
|
||||
#2d-circle|3|score|15|15|1
|
||||
2d-ellipse|3|score|15|15|1
|
||||
#2d-shapes|3|score|15|15|1
|
||||
2d-aashapes|3|score|15|15|1
|
||||
#2d-polys|3|score|15|15|1
|
||||
2d-text|3|score|15|15|1
|
||||
2d-blit|3|score|15|15|1
|
||||
2d-window|3|score|15|15|1
|
||||
|
||||
# The gears test score is derived from a test run on an HP Compaq nc8430
|
||||
# with an ATI Mobility Radeon X1600 Video (256MB) — this is a fairly
|
||||
# common modern adaptor with 3D. The baseline scores here are then
|
||||
# 1/66.6 of the values from that run, to bring them roughly in line with
|
||||
# George.
|
||||
ubgears|20|fps|33.4|33.4|3
|
||||
|
||||
# The grep and sysexec tests were added in 5.1.1; they are not index tests,
|
||||
# but these baseline scores were added for convenience.
|
||||
grep|30|lpm|1|1|3
|
||||
sysexec|10|lps|25|25|10
|
23
UnixBench/pgms/multi.sh
Executable file
23
UnixBench/pgms/multi.sh
Executable file
@ -0,0 +1,23 @@
|
||||
#! /bin/sh
|
||||
###############################################################################
|
||||
# The BYTE UNIX Benchmarks - Release 3
|
||||
# Module: multi.sh SID: 3.4 5/15/91 19:30:24
|
||||
#
|
||||
###############################################################################
|
||||
# Bug reports, patches, comments, suggestions should be sent to:
|
||||
#
|
||||
# Ben Smith or Rick Grehan at BYTE Magazine
|
||||
# ben@bytepb.UUCP rick_g@bytepb.UUCP
|
||||
#
|
||||
###############################################################################
|
||||
# Modification Log:
|
||||
#
|
||||
###############################################################################
|
||||
ID="@(#)multi.sh:3.4 -- 5/15/91 19:30:24";
|
||||
instance=1
|
||||
while [ $instance -le $1 ]; do
|
||||
/bin/sh "$UB_BINDIR/tst.sh" &
|
||||
instance=`expr $instance + 1`
|
||||
done
|
||||
wait
|
||||
|
20
UnixBench/pgms/tst.sh
Executable file
20
UnixBench/pgms/tst.sh
Executable file
@ -0,0 +1,20 @@
|
||||
#! /bin/sh
|
||||
###############################################################################
|
||||
# The BYTE UNIX Benchmarks - Release 3
|
||||
# Module: tst.sh SID: 3.4 5/15/91 19:30:24
|
||||
#
|
||||
###############################################################################
|
||||
# Bug reports, patches, comments, suggestions should be sent to:
|
||||
#
|
||||
# Ben Smith or Rick Grehan at BYTE Magazine
|
||||
# ben@bytepb.UUCP rick_g@bytepb.UUCP
|
||||
#
|
||||
###############################################################################
|
||||
# Modification Log:
|
||||
#
|
||||
###############################################################################
|
||||
ID="@(#)tst.sh:3.4 -- 5/15/91 19:30:24";
|
||||
sort >sort.$$ <sort.src
|
||||
od sort.$$ | sort -n -k 1 > od.$$
|
||||
grep the sort.$$ | tee grep.$$ | wc > wc.$$
|
||||
rm sort.$$ grep.$$ od.$$ wc.$$
|
14
UnixBench/pgms/unixbench.logo
Normal file
14
UnixBench/pgms/unixbench.logo
Normal file
@ -0,0 +1,14 @@
|
||||
|
||||
# # # # # # # ##### ###### # # #### # #
|
||||
# # ## # # # # # # # ## # # # # #
|
||||
# # # # # # ## ##### ##### # # # # ######
|
||||
# # # # # # ## # # # # # # # # #
|
||||
# # # ## # # # # # # # ## # # # #
|
||||
#### # # # # # ##### ###### # # #### # #
|
||||
|
||||
Version 5.1.2 Based on the Byte Magazine Unix Benchmark
|
||||
|
||||
Multi-CPU version Version 5 revisions by Ian Smith,
|
||||
Sunnyvale, CA, USA
|
||||
December 22, 2007 johantheghost at yahoo period com
|
||||
|
110
UnixBench/src/arith.c
Normal file
110
UnixBench/src/arith.c
Normal file
@ -0,0 +1,110 @@
|
||||
|
||||
/*******************************************************************************
|
||||
* The BYTE UNIX Benchmarks - Release 3
|
||||
* Module: arith.c SID: 3.3 5/15/91 19:30:19
|
||||
*
|
||||
*******************************************************************************
|
||||
* Bug reports, patches, comments, suggestions should be sent to:
|
||||
*
|
||||
* Ben Smith, Rick Grehan or Tom Yager
|
||||
* ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
|
||||
*
|
||||
*******************************************************************************
|
||||
* Modification Log:
|
||||
* May 12, 1989 - modified empty loops to avoid nullifying by optimizing
|
||||
* compilers
|
||||
* August 28, 1990 - changed timing relationship--now returns total number
|
||||
* of iterations (ty)
|
||||
* November 9, 1990 - made changes suggested by Keith Cantrell
|
||||
* (digi!kcantrel) to defeat optimization
|
||||
* to non-existence
|
||||
* October 22, 1997 - code cleanup to remove ANSI C compiler warnings
|
||||
* Andy Kahn <kahn@zk3.dec.com>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
char SCCSid[] = "@(#) @(#)arith.c:3.3 -- 5/15/91 19:30:19";
|
||||
/*
|
||||
* arithmetic test
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "timeit.c"
|
||||
|
||||
int dumb_stuff(int);
|
||||
|
||||
unsigned long iter;
|
||||
|
||||
/* this function is called when the alarm expires */
|
||||
void report()
|
||||
{
|
||||
fprintf(stderr,"COUNT|%ld|1|lps\n", iter);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
int duration;
|
||||
int result = 0;
|
||||
|
||||
if (argc != 2) {
|
||||
printf("Usage: %s duration\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
duration = atoi(argv[1]);
|
||||
|
||||
/* set up alarm call */
|
||||
iter = 0; /* init iteration count */
|
||||
wake_me(duration, report);
|
||||
|
||||
/* this loop will be interrupted by the alarm call */
|
||||
while (1)
|
||||
{
|
||||
/* in switching to time-based (instead of iteration-based),
|
||||
the following statement was added. It should not skew
|
||||
the timings too much--there was an increment and test
|
||||
in the "while" expression above. The only difference is
|
||||
that now we're incrementing a long instead of an int. (ty) */
|
||||
++iter;
|
||||
/* the loop calls a function to insure that something is done
|
||||
the results of the function are fed back in (just so they
|
||||
they won't be thrown away. A loop with
|
||||
unused assignments may get optimized out of existence */
|
||||
result = dumb_stuff(result);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/************************** dumb_stuff *******************/
|
||||
int dumb_stuff(i)
|
||||
int i;
|
||||
{
|
||||
#ifndef arithoh
|
||||
datum x, y, z;
|
||||
z = 0;
|
||||
#endif
|
||||
/*
|
||||
* 101
|
||||
* sum i*i/(i*i-1)
|
||||
* i=2
|
||||
*/
|
||||
/* notice that the i value is always reset by the loop */
|
||||
for (i=2; i<=101; i++)
|
||||
{
|
||||
#ifndef arithoh
|
||||
x = i;
|
||||
y = x*x;
|
||||
z += y/(y-1);
|
||||
}
|
||||
return(x+y+z);
|
||||
#else
|
||||
}
|
||||
return(0);
|
||||
#endif
|
||||
}
|
||||
|
597
UnixBench/src/big.c
Normal file
597
UnixBench/src/big.c
Normal file
@ -0,0 +1,597 @@
|
||||
/*******************************************************************************
|
||||
* The BYTE UNIX Benchmarks - Release 3
|
||||
* Module: big.c SID: 3.3 5/15/91 19:30:18
|
||||
*
|
||||
*******************************************************************************
|
||||
* Bug reports, patches, comments, suggestions should be sent to:
|
||||
*
|
||||
* Ben Smith, Rick Grehan or Tom Yager
|
||||
* ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
|
||||
*
|
||||
*******************************************************************************
|
||||
* Modification Log:
|
||||
* 10/22/97 - code cleanup to remove ANSI C compiler warnings
|
||||
* Andy Kahn <kahn@zk3.dec.com>
|
||||
*
|
||||
******************************************************************************/
|
||||
/*
|
||||
* dummy code for execl test [ old version of makework.c ]
|
||||
*
|
||||
* makework [ -r rate ] [ -c copyfile ] nusers
|
||||
*
|
||||
* job streams are specified on standard input with lines of the form
|
||||
* full_path_name_for_command [ options ] [ <standard_input_file ]
|
||||
*
|
||||
* "standard input" is send to all nuser instances of the commands in the
|
||||
* job streams at a rate not in excess of "rate" characters per second
|
||||
* per command
|
||||
*
|
||||
*/
|
||||
/* this code is included in other files and therefore has no SCCSid */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <signal.h>
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
|
||||
#define DEF_RATE 5.0
|
||||
#define GRANULE 5
|
||||
#define CHUNK 60
|
||||
#define MAXCHILD 12
|
||||
#define MAXWORK 10
|
||||
|
||||
/* Can't seem to get this declared in the headers... */
|
||||
extern int kill(pid_t pid, int sig);
|
||||
|
||||
void wrapup(char *);
|
||||
void onalarm(int);
|
||||
void pipeerr();
|
||||
void grunt();
|
||||
void getwork(void);
|
||||
#if debug
|
||||
void dumpwork(void);
|
||||
#endif
|
||||
void fatal(char *s);
|
||||
|
||||
float thres;
|
||||
float est_rate = DEF_RATE;
|
||||
int nusers; /* number of concurrent users to be simulated by
|
||||
* this process */
|
||||
int firstuser; /* ordinal identification of first user for this
|
||||
* process */
|
||||
int nwork = 0; /* number of job streams */
|
||||
int exit_status = 0; /* returned to parent */
|
||||
int sigpipe; /* pipe write error flag */
|
||||
|
||||
struct st_work {
|
||||
char *cmd; /* name of command to run */
|
||||
char **av; /* arguments to command */
|
||||
char *input; /* standard input buffer */
|
||||
int inpsize; /* size of standard input buffer */
|
||||
char *outf; /* standard output (filename) */
|
||||
} work[MAXWORK];
|
||||
|
||||
struct {
|
||||
int xmit; /* # characters sent */
|
||||
char *bp; /* std input buffer pointer */
|
||||
int blen; /* std input buffer length */
|
||||
int fd; /* stdin to command */
|
||||
int pid; /* child PID */
|
||||
char *line; /* start of input line */
|
||||
int firstjob; /* inital piece of work */
|
||||
int thisjob; /* current piece of work */
|
||||
} child[MAXCHILD], *cp;
|
||||
|
||||
int main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
int i;
|
||||
int l;
|
||||
int fcopy = 0; /* fd for copy output */
|
||||
int master = 1; /* the REAL master, == 0 for clones */
|
||||
int nchild; /* no. of children for a clone to run */
|
||||
int done; /* count of children finished */
|
||||
int output; /* aggregate output char count for all
|
||||
children */
|
||||
int c;
|
||||
int thiswork = 0; /* next job stream to allocate */
|
||||
int nch; /* # characters to write */
|
||||
int written; /* # characters actully written */
|
||||
char logname[15]; /* name of the log file(s) */
|
||||
int pvec[2]; /* for pipes */
|
||||
char *p;
|
||||
char *prog; /* my name */
|
||||
|
||||
#if ! debug
|
||||
freopen("masterlog.00", "a", stderr);
|
||||
#endif
|
||||
prog = argv[0];
|
||||
while (argc > 1 && argv[1][0] == '-') {
|
||||
p = &argv[1][1];
|
||||
argc--;
|
||||
argv++;
|
||||
while (*p) {
|
||||
switch (*p) {
|
||||
case 'r':
|
||||
est_rate = atoi(argv[1]);
|
||||
sscanf(argv[1], "%f", &est_rate);
|
||||
if (est_rate <= 0) {
|
||||
fprintf(stderr, "%s: bad rate, reset to %.2f chars/sec\n", prog, DEF_RATE);
|
||||
est_rate = DEF_RATE;
|
||||
}
|
||||
argc--;
|
||||
argv++;
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
fcopy = open(argv[1], 1);
|
||||
if (fcopy < 0)
|
||||
fcopy = creat(argv[1], 0600);
|
||||
if (fcopy < 0) {
|
||||
fprintf(stderr, "%s: cannot open copy file '%s'\n",
|
||||
prog, argv[1]);
|
||||
exit(2);
|
||||
}
|
||||
lseek(fcopy, 0L, 2); /* append at end of file */
|
||||
argc--;
|
||||
argv++;
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "%s: bad flag '%c'\n", prog, *p);
|
||||
exit(4);
|
||||
}
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "%s: missing nusers\n", prog);
|
||||
exit(4);
|
||||
}
|
||||
|
||||
nusers = atoi(argv[1]);
|
||||
if (nusers < 1) {
|
||||
fprintf(stderr, "%s: impossible nusers (%d<-%s)\n", prog, nusers, argv[1]);
|
||||
exit(4);
|
||||
}
|
||||
fprintf(stderr, "%d Users\n", nusers);
|
||||
argc--;
|
||||
argv++;
|
||||
|
||||
/* build job streams */
|
||||
getwork();
|
||||
#if debug
|
||||
dumpwork();
|
||||
#endif
|
||||
|
||||
/* clone copies of myself to run up to MAXCHILD jobs each */
|
||||
firstuser = MAXCHILD;
|
||||
fprintf(stderr, "master pid %d\n", getpid());
|
||||
fflush(stderr);
|
||||
while (nusers > MAXCHILD) {
|
||||
fflush(stderr);
|
||||
if (nusers >= 2*MAXCHILD)
|
||||
/* the next clone must run MAXCHILD jobs */
|
||||
nchild = MAXCHILD;
|
||||
else
|
||||
/* the next clone must run the leftover jobs */
|
||||
nchild = nusers - MAXCHILD;
|
||||
if ((l = fork()) == -1) {
|
||||
/* fork failed */
|
||||
fatal("** clone fork failed **\n");
|
||||
goto bepatient;
|
||||
} else if (l > 0) {
|
||||
fprintf(stderr, "master clone pid %d\n", l);
|
||||
/* I am the master with nchild fewer jobs to run */
|
||||
nusers -= nchild;
|
||||
firstuser += MAXCHILD;
|
||||
continue;
|
||||
} else {
|
||||
/* I am a clone, run MAXCHILD jobs */
|
||||
#if ! debug
|
||||
sprintf(logname, "masterlog.%02d", firstuser/MAXCHILD);
|
||||
freopen(logname, "w", stderr);
|
||||
#endif
|
||||
master = 0;
|
||||
nusers = nchild;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (master)
|
||||
firstuser = 0;
|
||||
|
||||
close(0);
|
||||
for (i = 0; i < nusers; i++ ) {
|
||||
fprintf(stderr, "user %d job %d ", firstuser+i, thiswork);
|
||||
if (pipe(pvec) == -1) {
|
||||
/* this is fatal */
|
||||
fatal("** pipe failed **\n");
|
||||
goto bepatient;
|
||||
}
|
||||
fflush(stderr);
|
||||
if ((child[i].pid = fork()) == 0) {
|
||||
int fd;
|
||||
/* the command */
|
||||
if (pvec[0] != 0) {
|
||||
close(0);
|
||||
dup(pvec[0]);
|
||||
}
|
||||
#if ! debug
|
||||
sprintf(logname, "userlog.%02d", firstuser+i);
|
||||
freopen(logname, "w", stderr);
|
||||
#endif
|
||||
for (fd = 3; fd < 24; fd++)
|
||||
close(fd);
|
||||
if (work[thiswork].outf[0] != '\0') {
|
||||
/* redirect std output */
|
||||
char *q;
|
||||
for (q = work[thiswork].outf; *q != '\n'; q++) ;
|
||||
*q = '\0';
|
||||
if (freopen(work[thiswork].outf, "w", stdout) == NULL) {
|
||||
fprintf(stderr, "makework: cannot open %s for std output\n",
|
||||
work[thiswork].outf);
|
||||
fflush(stderr);
|
||||
}
|
||||
*q = '\n';
|
||||
}
|
||||
execv(work[thiswork].cmd, work[thiswork].av);
|
||||
/* don't expect to get here! */
|
||||
fatal("** exec failed **\n");
|
||||
goto bepatient;
|
||||
}
|
||||
else if (child[i].pid == -1) {
|
||||
fatal("** fork failed **\n");
|
||||
goto bepatient;
|
||||
}
|
||||
else {
|
||||
close(pvec[0]);
|
||||
child[i].fd = pvec[1];
|
||||
child[i].line = child[i].bp = work[thiswork].input;
|
||||
child[i].blen = work[thiswork].inpsize;
|
||||
child[i].thisjob = thiswork;
|
||||
child[i].firstjob = thiswork;
|
||||
fprintf(stderr, "pid %d pipe fd %d", child[i].pid, child[i].fd);
|
||||
if (work[thiswork].outf[0] != '\0') {
|
||||
char *q;
|
||||
fprintf(stderr, " > ");
|
||||
for (q=work[thiswork].outf; *q != '\n'; q++)
|
||||
fputc(*q, stderr);
|
||||
}
|
||||
fputc('\n', stderr);
|
||||
thiswork++;
|
||||
if (thiswork >= nwork)
|
||||
thiswork = 0;
|
||||
}
|
||||
}
|
||||
fflush(stderr);
|
||||
|
||||
srand(time(0));
|
||||
thres = 0;
|
||||
done = output = 0;
|
||||
for (i = 0; i < nusers; i++) {
|
||||
if (child[i].blen == 0)
|
||||
done++;
|
||||
else
|
||||
thres += est_rate * GRANULE;
|
||||
}
|
||||
est_rate = thres;
|
||||
|
||||
signal(SIGALRM, onalarm);
|
||||
signal(SIGPIPE, pipeerr);
|
||||
alarm(GRANULE);
|
||||
while (done < nusers) {
|
||||
for (i = 0; i < nusers; i++) {
|
||||
cp = &child[i];
|
||||
if (cp->xmit >= cp->blen) continue;
|
||||
l = rand() % CHUNK + 1; /* 1-CHUNK chars */
|
||||
if (l == 0) continue;
|
||||
if (cp->xmit + l > cp->blen)
|
||||
l = cp->blen - cp->xmit;
|
||||
p = cp->bp;
|
||||
cp->bp += l;
|
||||
cp->xmit += l;
|
||||
#if debug
|
||||
fprintf(stderr, "child %d, %d processed, %d to go\n", i, cp->xmit, cp->blen - cp->xmit);
|
||||
#endif
|
||||
while (p < cp->bp) {
|
||||
if (*p == '\n' || (p == &cp->bp[-1] && cp->xmit >= cp->blen)) {
|
||||
/* write it out */
|
||||
nch = p - cp->line + 1;
|
||||
if ((written = write(cp->fd, cp->line, nch)) != nch) {
|
||||
/* argh! */
|
||||
cp->line[nch] = '\0';
|
||||
fprintf(stderr, "user %d job %d cmd %s ",
|
||||
firstuser+i, cp->thisjob, cp->line);
|
||||
fprintf(stderr, "write(,,%d) returns %d\n", nch, written);
|
||||
if (sigpipe)
|
||||
fatal("** SIGPIPE error **\n");
|
||||
else
|
||||
fatal("** write error **\n");
|
||||
goto bepatient;
|
||||
|
||||
}
|
||||
if (fcopy)
|
||||
write(fcopy, cp->line, p - cp->line + 1);
|
||||
#if debug
|
||||
fprintf(stderr, "child %d gets \"", i);
|
||||
{
|
||||
char *q = cp->line;
|
||||
while (q <= p) {
|
||||
if (*q >= ' ' && *q <= '~')
|
||||
fputc(*q, stderr);
|
||||
else
|
||||
fprintf(stderr, "\\%03o", *q);
|
||||
q++;
|
||||
}
|
||||
}
|
||||
fputc('"', stderr);
|
||||
#endif
|
||||
cp->line = &p[1];
|
||||
}
|
||||
p++;
|
||||
}
|
||||
if (cp->xmit >= cp->blen) {
|
||||
done++;
|
||||
close(cp->fd);
|
||||
#if debug
|
||||
fprintf(stderr, "child %d, close std input\n", i);
|
||||
#endif
|
||||
}
|
||||
output += l;
|
||||
}
|
||||
while (output > thres) {
|
||||
pause();
|
||||
#if debug
|
||||
fprintf(stderr, "after pause: output, thres, done %d %.2f %d\n", output, thres, done);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
bepatient:
|
||||
alarm(0);
|
||||
/****
|
||||
* If everything is going OK, we should simply be able to keep
|
||||
* looping unitil 'wait' fails, however some descendent process may
|
||||
* be in a state from which it can never exit, and so a timeout
|
||||
* is used.
|
||||
* 5 minutes should be ample, since the time to run all jobs is of
|
||||
* the order of 5-10 minutes, however some machines are painfully slow,
|
||||
* so the timeout has been set at 20 minutes (1200 seconds).
|
||||
****/
|
||||
signal(SIGALRM, grunt);
|
||||
alarm(1200);
|
||||
while ((c = wait(&l)) != -1) {
|
||||
for (i = 0; i < nusers; i++) {
|
||||
if (c == child[i].pid) {
|
||||
fprintf(stderr, "user %d job %d pid %d done", firstuser+i, child[i].thisjob, c);
|
||||
if (l != 0) {
|
||||
if (l & 0x7f)
|
||||
fprintf(stderr, " status %d", l & 0x7f);
|
||||
if (l & 0xff00)
|
||||
fprintf(stderr, " exit code %d", (l>>8) & 0xff);
|
||||
exit_status = 4;
|
||||
}
|
||||
fputc('\n', stderr);
|
||||
c = child[i].pid = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (c != -1) {
|
||||
fprintf(stderr, "master clone done, pid %d ", c);
|
||||
if (l != 0) {
|
||||
if (l & 0x7f)
|
||||
fprintf(stderr, " status %d", l & 0x7f);
|
||||
if (l & 0xff00)
|
||||
fprintf(stderr, " exit code %d", (l>>8) & 0xff);
|
||||
exit_status = 4;
|
||||
}
|
||||
fputc('\n', stderr);
|
||||
}
|
||||
}
|
||||
alarm(0);
|
||||
wrapup("Finished waiting ...");
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void onalarm(int foo)
|
||||
{
|
||||
thres += est_rate;
|
||||
signal(SIGALRM, onalarm);
|
||||
alarm(GRANULE);
|
||||
}
|
||||
|
||||
void grunt()
|
||||
{
|
||||
/* timeout after label "bepatient" in main */
|
||||
exit_status = 4;
|
||||
wrapup("Timed out waiting for jobs to finish ...");
|
||||
}
|
||||
|
||||
void pipeerr()
|
||||
{
|
||||
sigpipe++;
|
||||
}
|
||||
|
||||
void wrapup(char *reason)
|
||||
{
|
||||
int i;
|
||||
int killed = 0;
|
||||
fflush(stderr);
|
||||
for (i = 0; i < nusers; i++) {
|
||||
if (child[i].pid > 0 && kill(child[i].pid, SIGKILL) != -1) {
|
||||
if (!killed) {
|
||||
killed++;
|
||||
fprintf(stderr, "%s\n", reason);
|
||||
fflush(stderr);
|
||||
}
|
||||
fprintf(stderr, "user %d job %d pid %d killed off\n", firstuser+i, child[i].thisjob, child[i].pid);
|
||||
fflush(stderr);
|
||||
}
|
||||
}
|
||||
exit(exit_status);
|
||||
}
|
||||
|
||||
#define MAXLINE 512
|
||||
void getwork(void)
|
||||
{
|
||||
int i;
|
||||
int f;
|
||||
int ac=0;
|
||||
char *lp = (void *)0;
|
||||
char *q = (void *)0;
|
||||
struct st_work *w = (void *)0;
|
||||
char line[MAXLINE];
|
||||
char c;
|
||||
|
||||
while (fgets(line, MAXLINE, stdin) != NULL) {
|
||||
if (nwork >= MAXWORK) {
|
||||
fprintf(stderr, "Too many jobs specified, .. increase MAXWORK\n");
|
||||
exit(4);
|
||||
}
|
||||
w = &work[nwork];
|
||||
lp = line;
|
||||
i = 1;
|
||||
while (*lp && *lp != ' ') {
|
||||
i++;
|
||||
lp++;
|
||||
}
|
||||
w->cmd = (char *)malloc(i);
|
||||
strncpy(w->cmd, line, i-1);
|
||||
w->cmd[i-1] = '\0';
|
||||
w->inpsize = 0;
|
||||
w->input = "";
|
||||
/* start to build arg list */
|
||||
ac = 2;
|
||||
w->av = (char **)malloc(2*sizeof(char *));
|
||||
q = w->cmd;
|
||||
while (*q) q++;
|
||||
q--;
|
||||
while (q >= w->cmd) {
|
||||
if (*q == '/') {
|
||||
q++;
|
||||
break;
|
||||
}
|
||||
q--;
|
||||
}
|
||||
w->av[0] = q;
|
||||
while (*lp) {
|
||||
if (*lp == ' ') {
|
||||
/* space */
|
||||
lp++;
|
||||
continue;
|
||||
}
|
||||
else if (*lp == '<') {
|
||||
/* standard input for this job */
|
||||
q = ++lp;
|
||||
while (*lp && *lp != ' ') lp++;
|
||||
c = *lp;
|
||||
*lp = '\0';
|
||||
if ((f = open(q, 0)) == -1) {
|
||||
fprintf(stderr, "cannot open input file (%s) for job %d\n",
|
||||
q, nwork);
|
||||
exit(4);
|
||||
}
|
||||
/* gobble input */
|
||||
w->input = (char *)malloc(512);
|
||||
while ((i = read(f, &w->input[w->inpsize], 512)) > 0) {
|
||||
w->inpsize += i;
|
||||
w->input = (char *)realloc(w->input, w->inpsize+512);
|
||||
}
|
||||
w->input = (char *)realloc(w->input, w->inpsize);
|
||||
close(f);
|
||||
/* extract stdout file name from line beginning "C=" */
|
||||
w->outf = "";
|
||||
for (q = w->input; q < &w->input[w->inpsize-10]; q++) {
|
||||
if (*q == '\n' && strncmp(&q[1], "C=", 2) == 0) {
|
||||
w->outf = &q[3];
|
||||
break;
|
||||
}
|
||||
}
|
||||
#if debug
|
||||
if (*w->outf) {
|
||||
fprintf(stderr, "stdout->");
|
||||
for (q=w->outf; *q != '\n'; q++)
|
||||
fputc(*q, stderr);
|
||||
fputc('\n', stderr);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
/* a command option */
|
||||
ac++;
|
||||
w->av = (char **)realloc(w->av, ac*sizeof(char *));
|
||||
q = lp;
|
||||
i = 1;
|
||||
while (*lp && *lp != ' ') {
|
||||
lp++;
|
||||
i++;
|
||||
}
|
||||
w->av[ac-2] = (char *)malloc(i);
|
||||
strncpy(w->av[ac-2], q, i-1);
|
||||
w->av[ac-2][i-1] = '\0';
|
||||
}
|
||||
}
|
||||
w->av[ac-1] = (char *)0;
|
||||
nwork++;
|
||||
}
|
||||
}
|
||||
|
||||
#if debug
|
||||
void dumpwork(void)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
|
||||
for (i = 0; i < nwork; i++) {
|
||||
fprintf(stderr, "job %d: cmd: %s\n", i, work[i].cmd);
|
||||
j = 0;
|
||||
while (work[i].av[j]) {
|
||||
fprintf(stderr, "argv[%d]: %s\n", j, work[i].av[j]);
|
||||
j++;
|
||||
}
|
||||
fprintf(stderr, "input: %d chars text: ", work[i].inpsize);
|
||||
if (work[i].input == (char *)0)
|
||||
fprintf(stderr, "<NULL>\n");
|
||||
else {
|
||||
register char *pend;
|
||||
char *p;
|
||||
char c;
|
||||
p = work[i].input;
|
||||
while (*p) {
|
||||
pend = p;
|
||||
while (*pend && *pend != '\n')
|
||||
pend++;
|
||||
c = *pend;
|
||||
*pend = '\0';
|
||||
fprintf(stderr, "%s\n", p);
|
||||
*pend = c;
|
||||
p = &pend[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void fatal(char *s)
|
||||
{
|
||||
int i;
|
||||
fprintf(stderr, s);
|
||||
fflush(stderr);
|
||||
perror("Reason?");
|
||||
fflush(stderr);
|
||||
for (i = 0; i < nusers; i++) {
|
||||
if (child[i].pid > 0 && kill(child[i].pid, SIGKILL) != -1) {
|
||||
fprintf(stderr, "pid %d killed off\n", child[i].pid);
|
||||
fflush(stderr);
|
||||
}
|
||||
}
|
||||
exit_status = 4;
|
||||
}
|
111
UnixBench/src/context1.c
Normal file
111
UnixBench/src/context1.c
Normal file
@ -0,0 +1,111 @@
|
||||
|
||||
/*******************************************************************************
|
||||
* The BYTE UNIX Benchmarks - Release 3
|
||||
* Module: context1.c SID: 3.3 5/15/91 19:30:18
|
||||
*
|
||||
*******************************************************************************
|
||||
* Bug reports, patches, comments, suggestions should be sent to:
|
||||
*
|
||||
* Ben Smith, Rick Grehan or Tom Yager
|
||||
* ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
|
||||
*
|
||||
*******************************************************************************
|
||||
* Modification Log:
|
||||
* $Header: context1.c,v 3.4 87/06/22 14:22:59 kjmcdonell Beta $
|
||||
* August 28, 1990 - changed timing routines--now returns total number of
|
||||
* iterations in specified time period
|
||||
* October 22, 1997 - code cleanup to remove ANSI C compiler warnings
|
||||
* Andy Kahn <kahn@zk3.dec.com>
|
||||
*
|
||||
******************************************************************************/
|
||||
char SCCSid[] = "@(#) @(#)context1.c:3.3 -- 5/15/91 19:30:18";
|
||||
/*
|
||||
* Context switching via synchronized unbuffered pipe i/o
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include "timeit.c"
|
||||
|
||||
unsigned long iter;
|
||||
|
||||
void report()
|
||||
{
|
||||
fprintf(stderr, "COUNT|%lu|1|lps\n", iter);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
int duration;
|
||||
unsigned long check;
|
||||
int p1[2], p2[2];
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "Usage: context duration\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
duration = atoi(argv[1]);
|
||||
|
||||
/* set up alarm call */
|
||||
iter = 0;
|
||||
wake_me(duration, report);
|
||||
|
||||
if (pipe(p1) || pipe(p2)) {
|
||||
perror("pipe create failed");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (fork()) { /* parent process */
|
||||
/* master, write p1 & read p2 */
|
||||
close(p1[0]); close(p2[1]);
|
||||
while (1) {
|
||||
if (write(p1[1], (char *)&iter, sizeof(iter)) != sizeof(iter)) {
|
||||
if ((errno != 0) && (errno != EINTR))
|
||||
perror("master write failed");
|
||||
exit(1);
|
||||
}
|
||||
if (read(p2[0], (char *)&check, sizeof(check)) != sizeof(check)) {
|
||||
if ((errno != 0) && (errno != EINTR))
|
||||
perror("master read failed");
|
||||
exit(1);
|
||||
}
|
||||
if (check != iter) {
|
||||
fprintf(stderr, "Master sync error: expect %lu, got %lu\n",
|
||||
iter, check);
|
||||
exit(2);
|
||||
}
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
else { /* child process */
|
||||
unsigned long iter1;
|
||||
|
||||
iter1 = 0;
|
||||
/* slave, read p1 & write p2 */
|
||||
close(p1[1]); close(p2[0]);
|
||||
while (1) {
|
||||
if (read(p1[0], (char *)&check, sizeof(check)) != sizeof(check)) {
|
||||
if ((errno != 0) && (errno != EINTR))
|
||||
perror("slave read failed");
|
||||
exit(1);
|
||||
}
|
||||
if (check != iter1) {
|
||||
fprintf(stderr, "Slave sync error: expect %lu, got %lu\n",
|
||||
iter, check);
|
||||
exit(2);
|
||||
}
|
||||
if (write(p2[1], (char *)&iter1, sizeof(iter1)) != sizeof(check)) {
|
||||
if ((errno != 0) && (errno != EINTR))
|
||||
perror("slave write failed");
|
||||
exit(1);
|
||||
}
|
||||
iter1++;
|
||||
}
|
||||
}
|
||||
}
|
435
UnixBench/src/dhry.h
Normal file
435
UnixBench/src/dhry.h
Normal file
@ -0,0 +1,435 @@
|
||||
/*****************************************************************************
|
||||
* The BYTE UNIX Benchmarks - Release 3
|
||||
* Module: dhry.h SID: 3.4 5/15/91 19:30:21
|
||||
*
|
||||
*****************************************************************************
|
||||
* Bug reports, patches, comments, suggestions should be sent to:
|
||||
*
|
||||
* Ben Smith, Rick Grehan or Tom Yager
|
||||
* ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
|
||||
*
|
||||
*****************************************************************************
|
||||
* Modification Log:
|
||||
* addapted from:
|
||||
*
|
||||
*
|
||||
* "DHRYSTONE" Benchmark Program
|
||||
* -----------------------------
|
||||
*
|
||||
* Version: C, Version 2.1
|
||||
*
|
||||
* File: dhry.h (part 1 of 3)
|
||||
*
|
||||
* Date: May 25, 1988
|
||||
*
|
||||
* Author: Reinhold P. Weicker
|
||||
* Siemens AG, AUT E 51
|
||||
* Postfach 3220
|
||||
* 8520 Erlangen
|
||||
* Germany (West)
|
||||
* Phone: [+49]-9131-7-20330
|
||||
* (8-17 Central European Time)
|
||||
* Usenet: ..!mcvax!unido!estevax!weicker
|
||||
*
|
||||
* Original Version (in Ada) published in
|
||||
* "Communications of the ACM" vol. 27., no. 10 (Oct. 1984),
|
||||
* pp. 1013 - 1030, together with the statistics
|
||||
* on which the distribution of statements etc. is based.
|
||||
*
|
||||
* In this C version, the following C library functions are used:
|
||||
* - strcpy, strcmp (inside the measurement loop)
|
||||
* - printf, scanf (outside the measurement loop)
|
||||
* In addition, Berkeley UNIX system calls "times ()" or "time ()"
|
||||
* are used for execution time measurement. For measurements
|
||||
* on other systems, these calls have to be changed.
|
||||
*
|
||||
* Collection of Results:
|
||||
* Reinhold Weicker (address see above) and
|
||||
*
|
||||
* Rick Richardson
|
||||
* PC Research. Inc.
|
||||
* 94 Apple Orchard Drive
|
||||
* Tinton Falls, NJ 07724
|
||||
* Phone: (201) 834-1378 (9-17 EST)
|
||||
* Usenet: ...!seismo!uunet!pcrat!rick
|
||||
*
|
||||
* Please send results to Rick Richardson and/or Reinhold Weicker.
|
||||
* Complete information should be given on hardware and software used.
|
||||
* Hardware information includes: Machine type, CPU, type and size
|
||||
* of caches; for microprocessors: clock frequency, memory speed
|
||||
* (number of wait states).
|
||||
* Software information includes: Compiler (and runtime library)
|
||||
* manufacturer and version, compilation switches, OS version.
|
||||
* The Operating System version may give an indication about the
|
||||
* compiler; Dhrystone itself performs no OS calls in the measurement loop.
|
||||
*
|
||||
* The complete output generated by the program should be mailed
|
||||
* such that at least some checks for correctness can be made.
|
||||
*
|
||||
***************************************************************************
|
||||
*
|
||||
* History: This version C/2.1 has been made for two reasons:
|
||||
*
|
||||
* 1) There is an obvious need for a common C version of
|
||||
* Dhrystone, since C is at present the most popular system
|
||||
* programming language for the class of processors
|
||||
* (microcomputers, minicomputers) where Dhrystone is used most.
|
||||
* There should be, as far as possible, only one C version of
|
||||
* Dhrystone such that results can be compared without
|
||||
* restrictions. In the past, the C versions distributed
|
||||
* by Rick Richardson (Version 1.1) and by Reinhold Weicker
|
||||
* had small (though not significant) differences.
|
||||
*
|
||||
* 2) As far as it is possible without changes to the Dhrystone
|
||||
* statistics, optimizing compilers should be prevented from
|
||||
* removing significant statements.
|
||||
*
|
||||
* This C version has been developed in cooperation with
|
||||
* Rick Richardson (Tinton Falls, NJ), it incorporates many
|
||||
* ideas from the "Version 1.1" distributed previously by
|
||||
* him over the UNIX network Usenet.
|
||||
* I also thank Chaim Benedelac (National Semiconductor),
|
||||
* David Ditzel (SUN), Earl Killian and John Mashey (MIPS),
|
||||
* Alan Smith and Rafael Saavedra-Barrera (UC at Berkeley)
|
||||
* for their help with comments on earlier versions of the
|
||||
* benchmark.
|
||||
*
|
||||
* Changes: In the initialization part, this version follows mostly
|
||||
* Rick Richardson's version distributed via Usenet, not the
|
||||
* version distributed earlier via floppy disk by Reinhold Weicker.
|
||||
* As a concession to older compilers, names have been made
|
||||
* unique within the first 8 characters.
|
||||
* Inside the measurement loop, this version follows the
|
||||
* version previously distributed by Reinhold Weicker.
|
||||
*
|
||||
* At several places in the benchmark, code has been added,
|
||||
* but within the measurement loop only in branches that
|
||||
* are not executed. The intention is that optimizing compilers
|
||||
* should be prevented from moving code out of the measurement
|
||||
* loop, or from removing code altogether. Since the statements
|
||||
* that are executed within the measurement loop have NOT been
|
||||
* changed, the numbers defining the "Dhrystone distribution"
|
||||
* (distribution of statements, operand types and locality)
|
||||
* still hold. Except for sophisticated optimizing compilers,
|
||||
* execution times for this version should be the same as
|
||||
* for previous versions.
|
||||
*
|
||||
* Since it has proven difficult to subtract the time for the
|
||||
* measurement loop overhead in a correct way, the loop check
|
||||
* has been made a part of the benchmark. This does have
|
||||
* an impact - though a very minor one - on the distribution
|
||||
* statistics which have been updated for this version.
|
||||
*
|
||||
* All changes within the measurement loop are described
|
||||
* and discussed in the companion paper "Rationale for
|
||||
* Dhrystone version 2".
|
||||
*
|
||||
* Because of the self-imposed limitation that the order and
|
||||
* distribution of the executed statements should not be
|
||||
* changed, there are still cases where optimizing compilers
|
||||
* may not generate code for some statements. To a certain
|
||||
* degree, this is unavoidable for small synthetic benchmarks.
|
||||
* Users of the benchmark are advised to check code listings
|
||||
* whether code is generated for all statements of Dhrystone.
|
||||
*
|
||||
* Version 2.1 is identical to version 2.0 distributed via
|
||||
* the UNIX network Usenet in March 1988 except that it corrects
|
||||
* some minor deficiencies that were found by users of version 2.0.
|
||||
* The only change within the measurement loop is that a
|
||||
* non-executed "else" part was added to the "if" statement in
|
||||
* Func_3, and a non-executed "else" part removed from Proc_3.
|
||||
*
|
||||
***************************************************************************
|
||||
*
|
||||
* Defines: The following "Defines" are possible:
|
||||
* -DREG=register (default: Not defined)
|
||||
* As an approximation to what an average C programmer
|
||||
* might do, the "register" storage class is applied
|
||||
* (if enabled by -DREG=register)
|
||||
* - for local variables, if they are used (dynamically)
|
||||
* five or more times
|
||||
* - for parameters if they are used (dynamically)
|
||||
* six or more times
|
||||
* Note that an optimal "register" strategy is
|
||||
* compiler-dependent, and that "register" declarations
|
||||
* do not necessarily lead to faster execution.
|
||||
* -DNOSTRUCTASSIGN (default: Not defined)
|
||||
* Define if the C compiler does not support
|
||||
* assignment of structures.
|
||||
* -DNOENUMS (default: Not defined)
|
||||
* Define if the C compiler does not support
|
||||
* enumeration types.
|
||||
* -DTIMES (default)
|
||||
* -DTIME
|
||||
* The "times" function of UNIX (returning process times)
|
||||
* or the "time" function (returning wallclock time)
|
||||
* is used for measurement.
|
||||
* For single user machines, "time ()" is adequate. For
|
||||
* multi-user machines where you cannot get single-user
|
||||
* access, use the "times ()" function. If you have
|
||||
* neither, use a stopwatch in the dead of night.
|
||||
* "printf"s are provided marking the points "Start Timer"
|
||||
* and "Stop Timer". DO NOT use the UNIX "time(1)"
|
||||
* command, as this will measure the total time to
|
||||
* run this program, which will (erroneously) include
|
||||
* the time to allocate storage (malloc) and to perform
|
||||
* the initialization.
|
||||
* -DHZ=nnn
|
||||
* In Berkeley UNIX, the function "times" returns process
|
||||
* time in 1/HZ seconds, with HZ = 60 for most systems.
|
||||
* CHECK YOUR SYSTEM DESCRIPTION BEFORE YOU JUST APPLY
|
||||
* A VALUE.
|
||||
*
|
||||
***************************************************************************
|
||||
*
|
||||
* Compilation model and measurement (IMPORTANT):
|
||||
*
|
||||
* This C version of Dhrystone consists of three files:
|
||||
* - dhry.h (this file, containing global definitions and comments)
|
||||
* - dhry_1.c (containing the code corresponding to Ada package Pack_1)
|
||||
* - dhry_2.c (containing the code corresponding to Ada package Pack_2)
|
||||
*
|
||||
* The following "ground rules" apply for measurements:
|
||||
* - Separate compilation
|
||||
* - No procedure merging
|
||||
* - Otherwise, compiler optimizations are allowed but should be indicated
|
||||
* - Default results are those without register declarations
|
||||
* See the companion paper "Rationale for Dhrystone Version 2" for a more
|
||||
* detailed discussion of these ground rules.
|
||||
*
|
||||
* For 16-Bit processors (e.g. 80186, 80286), times for all compilation
|
||||
* models ("small", "medium", "large" etc.) should be given if possible,
|
||||
* together with a definition of these models for the compiler system used.
|
||||
*
|
||||
**************************************************************************
|
||||
*
|
||||
* Dhrystone (C version) statistics:
|
||||
*
|
||||
* [Comment from the first distribution, updated for version 2.
|
||||
* Note that because of language differences, the numbers are slightly
|
||||
* different from the Ada version.]
|
||||
*
|
||||
* The following program contains statements of a high level programming
|
||||
* language (here: C) in a distribution considered representative:
|
||||
*
|
||||
* assignments 52 (51.0 %)
|
||||
* control statements 33 (32.4 %)
|
||||
* procedure, function calls 17 (16.7 %)
|
||||
*
|
||||
* 103 statements are dynamically executed. The program is balanced with
|
||||
* respect to the three aspects:
|
||||
*
|
||||
* - statement type
|
||||
* - operand type
|
||||
* - operand locality
|
||||
* operand global, local, parameter, or constant.
|
||||
*
|
||||
* The combination of these three aspects is balanced only approximately.
|
||||
*
|
||||
* 1. Statement Type:
|
||||
* ----------------- number
|
||||
*
|
||||
* V1 = V2 9
|
||||
* (incl. V1 = F(..)
|
||||
* V = Constant 12
|
||||
* Assignment, 7
|
||||
* with array element
|
||||
* Assignment, 6
|
||||
* with record component
|
||||
* --
|
||||
* 34 34
|
||||
*
|
||||
* X = Y +|-|"&&"|"|" Z 5
|
||||
* X = Y +|-|"==" Constant 6
|
||||
* X = X +|- 1 3
|
||||
* X = Y *|/ Z 2
|
||||
* X = Expression, 1
|
||||
* two operators
|
||||
* X = Expression, 1
|
||||
* three operators
|
||||
* --
|
||||
* 18 18
|
||||
*
|
||||
* if .... 14
|
||||
* with "else" 7
|
||||
* without "else" 7
|
||||
* executed 3
|
||||
* not executed 4
|
||||
* for ... 7 | counted every time
|
||||
* while ... 4 | the loop condition
|
||||
* do ... while 1 | is evaluated
|
||||
* switch ... 1
|
||||
* break 1
|
||||
* declaration with 1
|
||||
* initialization
|
||||
* --
|
||||
* 34 34
|
||||
*
|
||||
* P (...) procedure call 11
|
||||
* user procedure 10
|
||||
* library procedure 1
|
||||
* X = F (...)
|
||||
* function call 6
|
||||
* user function 5
|
||||
* library function 1
|
||||
* --
|
||||
* 17 17
|
||||
* ---
|
||||
* 103
|
||||
*
|
||||
* The average number of parameters in procedure or function calls
|
||||
* is 1.82 (not counting the function values as implicit parameters).
|
||||
*
|
||||
*
|
||||
* 2. Operators
|
||||
* ------------
|
||||
* number approximate
|
||||
* percentage
|
||||
*
|
||||
* Arithmetic 32 50.8
|
||||
*
|
||||
* + 21 33.3
|
||||
* - 7 11.1
|
||||
* * 3 4.8
|
||||
* / (int div) 1 1.6
|
||||
*
|
||||
* Comparison 27 42.8
|
||||
*
|
||||
* == 9 14.3
|
||||
* /= 4 6.3
|
||||
* > 1 1.6
|
||||
* < 3 4.8
|
||||
* >= 1 1.6
|
||||
* <= 9 14.3
|
||||
*
|
||||
* Logic 4 6.3
|
||||
*
|
||||
* && (AND-THEN) 1 1.6
|
||||
* | (OR) 1 1.6
|
||||
* ! (NOT) 2 3.2
|
||||
*
|
||||
* -- -----
|
||||
* 63 100.1
|
||||
*
|
||||
*
|
||||
* 3. Operand Type (counted once per operand reference):
|
||||
* ---------------
|
||||
* number approximate
|
||||
* percentage
|
||||
*
|
||||
* Integer 175 72.3 %
|
||||
* Character 45 18.6 %
|
||||
* Pointer 12 5.0 %
|
||||
* String30 6 2.5 %
|
||||
* Array 2 0.8 %
|
||||
* Record 2 0.8 %
|
||||
* --- -------
|
||||
* 242 100.0 %
|
||||
*
|
||||
* When there is an access path leading to the final operand (e.g. a record
|
||||
* component), only the final data type on the access path is counted.
|
||||
*
|
||||
*
|
||||
* 4. Operand Locality:
|
||||
* -------------------
|
||||
* number approximate
|
||||
* percentage
|
||||
*
|
||||
* local variable 114 47.1 %
|
||||
* global variable 22 9.1 %
|
||||
* parameter 45 18.6 %
|
||||
* value 23 9.5 %
|
||||
* reference 22 9.1 %
|
||||
* function result 6 2.5 %
|
||||
* constant 55 22.7 %
|
||||
* --- -------
|
||||
* 242 100.0 %
|
||||
*
|
||||
*
|
||||
* The program does not compute anything meaningful, but it is syntactically
|
||||
* and semantically correct. All variables have a value assigned to them
|
||||
* before they are used as a source operand.
|
||||
*
|
||||
* There has been no explicit effort to account for the effects of a
|
||||
* cache, or to balance the use of long or short displacements for code or
|
||||
* data.
|
||||
*
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/* Compiler and system dependent definitions: */
|
||||
|
||||
#ifndef TIME
|
||||
#define TIMES
|
||||
#endif
|
||||
/* Use times(2) time function unless */
|
||||
/* explicitly defined otherwise */
|
||||
|
||||
#ifdef TIMES
|
||||
#include <sys/types.h>
|
||||
#include <sys/times.h>
|
||||
/* for "times" */
|
||||
#endif
|
||||
|
||||
#define Mic_secs_Per_Second 1000000.0
|
||||
/* Berkeley UNIX C returns process times in seconds/HZ */
|
||||
|
||||
#ifdef NOSTRUCTASSIGN
|
||||
#define structassign(d, s) memcpy(&(d), &(s), sizeof(d))
|
||||
#else
|
||||
#define structassign(d, s) d = s
|
||||
#endif
|
||||
|
||||
#ifdef NOENUM
|
||||
#define Ident_1 0
|
||||
#define Ident_2 1
|
||||
#define Ident_3 2
|
||||
#define Ident_4 3
|
||||
#define Ident_5 4
|
||||
typedef int Enumeration;
|
||||
#else
|
||||
typedef enum {Ident_1, Ident_2, Ident_3, Ident_4, Ident_5}
|
||||
Enumeration;
|
||||
#endif
|
||||
/* for boolean and enumeration types in Ada, Pascal */
|
||||
|
||||
/* General definitions: */
|
||||
|
||||
#include <stdio.h>
|
||||
/* for strcpy, strcmp */
|
||||
|
||||
#define Null 0
|
||||
/* Value of a Null pointer */
|
||||
#define true 1
|
||||
#define false 0
|
||||
|
||||
typedef int One_Thirty;
|
||||
typedef int One_Fifty;
|
||||
typedef char Capital_Letter;
|
||||
typedef int Boolean;
|
||||
typedef char Str_30 [31];
|
||||
typedef int Arr_1_Dim [50];
|
||||
typedef int Arr_2_Dim [50] [50];
|
||||
|
||||
typedef struct record
|
||||
{
|
||||
struct record *Ptr_Comp;
|
||||
Enumeration Discr;
|
||||
union {
|
||||
struct {
|
||||
Enumeration Enum_Comp;
|
||||
int Int_Comp;
|
||||
char Str_Comp [31];
|
||||
} var_1;
|
||||
struct {
|
||||
Enumeration E_Comp_2;
|
||||
char Str_2_Comp [31];
|
||||
} var_2;
|
||||
struct {
|
||||
char Ch_1_Comp;
|
||||
char Ch_2_Comp;
|
||||
} var_3;
|
||||
} variant;
|
||||
} Rec_Type, *Rec_Pointer;
|
||||
|
431
UnixBench/src/dhry_1.c
Normal file
431
UnixBench/src/dhry_1.c
Normal file
@ -0,0 +1,431 @@
|
||||
/*****************************************************************************
|
||||
* The BYTE UNIX Benchmarks - Release 3
|
||||
* Module: dhry_1.c SID: 3.4 5/15/91 19:30:21
|
||||
*
|
||||
*****************************************************************************
|
||||
* Bug reports, patches, comments, suggestions should be sent to:
|
||||
*
|
||||
* Ben Smith, Rick Grehan or Tom Yager
|
||||
* ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
|
||||
*
|
||||
*****************************************************************************
|
||||
*
|
||||
* *** WARNING **** With BYTE's modifications applied, results obtained with
|
||||
* ******* this version of the Dhrystone program may not be applicable
|
||||
* to other versions.
|
||||
*
|
||||
* Modification Log:
|
||||
* 10/22/97 - code cleanup to remove ANSI C compiler warnings
|
||||
* Andy Kahn <kahn@zk3.dec.com>
|
||||
*
|
||||
* Adapted from:
|
||||
*
|
||||
* "DHRYSTONE" Benchmark Program
|
||||
* -----------------------------
|
||||
*
|
||||
* Version: C, Version 2.1
|
||||
*
|
||||
* File: dhry_1.c (part 2 of 3)
|
||||
*
|
||||
* Date: May 25, 1988
|
||||
*
|
||||
* Author: Reinhold P. Weicker
|
||||
*
|
||||
***************************************************************************/
|
||||
char SCCSid[] = "@(#) @(#)dhry_1.c:3.4 -- 5/15/91 19:30:21";
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "dhry.h"
|
||||
#include "timeit.c"
|
||||
|
||||
unsigned long Run_Index;
|
||||
|
||||
void report()
|
||||
{
|
||||
fprintf(stderr,"COUNT|%ld|1|lps\n", Run_Index);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* Global Variables: */
|
||||
|
||||
Rec_Pointer Ptr_Glob,
|
||||
Next_Ptr_Glob;
|
||||
int Int_Glob;
|
||||
Boolean Bool_Glob;
|
||||
char Ch_1_Glob,
|
||||
Ch_2_Glob;
|
||||
int Arr_1_Glob [50];
|
||||
int Arr_2_Glob [50] [50];
|
||||
|
||||
Enumeration Func_1 ();
|
||||
/* forward declaration necessary since Enumeration may not simply be int */
|
||||
|
||||
#ifndef REG
|
||||
Boolean Reg = false;
|
||||
#define REG
|
||||
/* REG becomes defined as empty */
|
||||
/* i.e. no register variables */
|
||||
#else
|
||||
Boolean Reg = true;
|
||||
#endif
|
||||
|
||||
/* variables for time measurement: */
|
||||
|
||||
#ifdef TIMES
|
||||
struct tms time_info;
|
||||
extern int times ();
|
||||
/* see library function "times" */
|
||||
#define Too_Small_Time 120
|
||||
/* Measurements should last at least about 2 seconds */
|
||||
#endif
|
||||
#ifdef TIME
|
||||
extern long time();
|
||||
/* see library function "time" */
|
||||
#define Too_Small_Time 2
|
||||
/* Measurements should last at least 2 seconds */
|
||||
#endif
|
||||
|
||||
long Begin_Time,
|
||||
End_Time,
|
||||
User_Time;
|
||||
float Microseconds,
|
||||
Dhrystones_Per_Second;
|
||||
|
||||
/* end of variables for time measurement */
|
||||
|
||||
void Proc_1 (REG Rec_Pointer Ptr_Val_Par);
|
||||
void Proc_2 (One_Fifty *Int_Par_Ref);
|
||||
void Proc_3 (Rec_Pointer *Ptr_Ref_Par);
|
||||
void Proc_4 (void);
|
||||
void Proc_5 (void);
|
||||
|
||||
|
||||
extern Boolean Func_2(Str_30, Str_30);
|
||||
extern void Proc_6(Enumeration, Enumeration *);
|
||||
extern void Proc_7(One_Fifty, One_Fifty, One_Fifty *);
|
||||
extern void Proc_8(Arr_1_Dim, Arr_2_Dim, int, int);
|
||||
|
||||
int main (argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
/* main program, corresponds to procedures */
|
||||
/* Main and Proc_0 in the Ada version */
|
||||
{
|
||||
int duration;
|
||||
One_Fifty Int_1_Loc;
|
||||
REG One_Fifty Int_2_Loc;
|
||||
One_Fifty Int_3_Loc;
|
||||
REG char Ch_Index;
|
||||
Enumeration Enum_Loc;
|
||||
Str_30 Str_1_Loc;
|
||||
Str_30 Str_2_Loc;
|
||||
|
||||
/* Initializations */
|
||||
|
||||
Next_Ptr_Glob = (Rec_Pointer) malloc (sizeof (Rec_Type));
|
||||
Ptr_Glob = (Rec_Pointer) malloc (sizeof (Rec_Type));
|
||||
|
||||
Ptr_Glob->Ptr_Comp = Next_Ptr_Glob;
|
||||
Ptr_Glob->Discr = Ident_1;
|
||||
Ptr_Glob->variant.var_1.Enum_Comp = Ident_3;
|
||||
Ptr_Glob->variant.var_1.Int_Comp = 40;
|
||||
strcpy (Ptr_Glob->variant.var_1.Str_Comp,
|
||||
"DHRYSTONE PROGRAM, SOME STRING");
|
||||
strcpy (Str_1_Loc, "DHRYSTONE PROGRAM, 1'ST STRING");
|
||||
|
||||
Arr_2_Glob [8][7] = 10;
|
||||
/* Was missing in published program. Without this statement, */
|
||||
/* Arr_2_Glob [8][7] would have an undefined value. */
|
||||
/* Warning: With 16-Bit processors and Number_Of_Runs > 32000, */
|
||||
/* overflow may occur for this array element. */
|
||||
|
||||
#ifdef PRATTLE
|
||||
printf ("\n");
|
||||
printf ("Dhrystone Benchmark, Version 2.1 (Language: C)\n");
|
||||
printf ("\n");
|
||||
if (Reg)
|
||||
{
|
||||
printf ("Program compiled with 'register' attribute\n");
|
||||
printf ("\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf ("Program compiled without 'register' attribute\n");
|
||||
printf ("\n");
|
||||
}
|
||||
printf ("Please give the number of runs through the benchmark: ");
|
||||
{
|
||||
int n;
|
||||
scanf ("%d", &n);
|
||||
Number_Of_Runs = n;
|
||||
}
|
||||
printf ("\n");
|
||||
|
||||
printf ("Execution starts, %d runs through Dhrystone\n", Number_Of_Runs);
|
||||
#endif /* PRATTLE */
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "Usage: %s duration\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
duration = atoi(argv[1]);
|
||||
Run_Index = 0;
|
||||
wake_me(duration, report);
|
||||
|
||||
/***************/
|
||||
/* Start timer */
|
||||
/***************/
|
||||
|
||||
#ifdef SELF_TIMED
|
||||
#ifdef TIMES
|
||||
times (&time_info);
|
||||
Begin_Time = (long) time_info.tms_utime;
|
||||
#endif
|
||||
#ifdef TIME
|
||||
Begin_Time = time ( (long *) 0);
|
||||
#endif
|
||||
#endif /* SELF_TIMED */
|
||||
|
||||
for (Run_Index = 1; ; ++Run_Index)
|
||||
{
|
||||
|
||||
Proc_5();
|
||||
Proc_4();
|
||||
/* Ch_1_Glob == 'A', Ch_2_Glob == 'B', Bool_Glob == true */
|
||||
Int_1_Loc = 2;
|
||||
Int_2_Loc = 3;
|
||||
strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 2'ND STRING");
|
||||
Enum_Loc = Ident_2;
|
||||
Bool_Glob = ! Func_2 (Str_1_Loc, Str_2_Loc);
|
||||
/* Bool_Glob == 1 */
|
||||
while (Int_1_Loc < Int_2_Loc) /* loop body executed once */
|
||||
{
|
||||
Int_3_Loc = 5 * Int_1_Loc - Int_2_Loc;
|
||||
/* Int_3_Loc == 7 */
|
||||
Proc_7 (Int_1_Loc, Int_2_Loc, &Int_3_Loc);
|
||||
/* Int_3_Loc == 7 */
|
||||
Int_1_Loc += 1;
|
||||
} /* while */
|
||||
/* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
|
||||
Proc_8 (Arr_1_Glob, Arr_2_Glob, Int_1_Loc, Int_3_Loc);
|
||||
/* Int_Glob == 5 */
|
||||
Proc_1 (Ptr_Glob);
|
||||
for (Ch_Index = 'A'; Ch_Index <= Ch_2_Glob; ++Ch_Index)
|
||||
/* loop body executed twice */
|
||||
{
|
||||
if (Enum_Loc == Func_1 (Ch_Index, 'C'))
|
||||
/* then, not executed */
|
||||
{
|
||||
Proc_6 (Ident_1, &Enum_Loc);
|
||||
strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 3'RD STRING");
|
||||
Int_2_Loc = Run_Index;
|
||||
Int_Glob = Run_Index;
|
||||
}
|
||||
}
|
||||
/* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
|
||||
Int_2_Loc = Int_2_Loc * Int_1_Loc;
|
||||
Int_1_Loc = Int_2_Loc / Int_3_Loc;
|
||||
Int_2_Loc = 7 * (Int_2_Loc - Int_3_Loc) - Int_1_Loc;
|
||||
/* Int_1_Loc == 1, Int_2_Loc == 13, Int_3_Loc == 7 */
|
||||
Proc_2 (&Int_1_Loc);
|
||||
/* Int_1_Loc == 5 */
|
||||
|
||||
} /* loop "for Run_Index" */
|
||||
|
||||
/**************/
|
||||
/* Stop timer */
|
||||
/**************/
|
||||
#ifdef SELF_TIMED
|
||||
#ifdef TIMES
|
||||
times (&time_info);
|
||||
End_Time = (long) time_info.tms_utime;
|
||||
#endif
|
||||
#ifdef TIME
|
||||
End_Time = time ( (long *) 0);
|
||||
#endif
|
||||
#endif /* SELF_TIMED */
|
||||
|
||||
/* BYTE version never executes this stuff */
|
||||
#ifdef SELF_TIMED
|
||||
printf ("Execution ends\n");
|
||||
printf ("\n");
|
||||
printf ("Final values of the variables used in the benchmark:\n");
|
||||
printf ("\n");
|
||||
printf ("Int_Glob: %d\n", Int_Glob);
|
||||
printf (" should be: %d\n", 5);
|
||||
printf ("Bool_Glob: %d\n", Bool_Glob);
|
||||
printf (" should be: %d\n", 1);
|
||||
printf ("Ch_1_Glob: %c\n", Ch_1_Glob);
|
||||
printf (" should be: %c\n", 'A');
|
||||
printf ("Ch_2_Glob: %c\n", Ch_2_Glob);
|
||||
printf (" should be: %c\n", 'B');
|
||||
printf ("Arr_1_Glob[8]: %d\n", Arr_1_Glob[8]);
|
||||
printf (" should be: %d\n", 7);
|
||||
printf ("Arr_2_Glob[8][7]: %d\n", Arr_2_Glob[8][7]);
|
||||
printf (" should be: Number_Of_Runs + 10\n");
|
||||
printf ("Ptr_Glob->\n");
|
||||
printf (" Ptr_Comp: %d\n", (int) Ptr_Glob->Ptr_Comp);
|
||||
printf (" should be: (implementation-dependent)\n");
|
||||
printf (" Discr: %d\n", Ptr_Glob->Discr);
|
||||
printf (" should be: %d\n", 0);
|
||||
printf (" Enum_Comp: %d\n", Ptr_Glob->variant.var_1.Enum_Comp);
|
||||
printf (" should be: %d\n", 2);
|
||||
printf (" Int_Comp: %d\n", Ptr_Glob->variant.var_1.Int_Comp);
|
||||
printf (" should be: %d\n", 17);
|
||||
printf (" Str_Comp: %s\n", Ptr_Glob->variant.var_1.Str_Comp);
|
||||
printf (" should be: DHRYSTONE PROGRAM, SOME STRING\n");
|
||||
printf ("Next_Ptr_Glob->\n");
|
||||
printf (" Ptr_Comp: %d\n", (int) Next_Ptr_Glob->Ptr_Comp);
|
||||
printf (" should be: (implementation-dependent), same as above\n");
|
||||
printf (" Discr: %d\n", Next_Ptr_Glob->Discr);
|
||||
printf (" should be: %d\n", 0);
|
||||
printf (" Enum_Comp: %d\n", Next_Ptr_Glob->variant.var_1.Enum_Comp);
|
||||
printf (" should be: %d\n", 1);
|
||||
printf (" Int_Comp: %d\n", Next_Ptr_Glob->variant.var_1.Int_Comp);
|
||||
printf (" should be: %d\n", 18);
|
||||
printf (" Str_Comp: %s\n",
|
||||
Next_Ptr_Glob->variant.var_1.Str_Comp);
|
||||
printf (" should be: DHRYSTONE PROGRAM, SOME STRING\n");
|
||||
printf ("Int_1_Loc: %d\n", Int_1_Loc);
|
||||
printf (" should be: %d\n", 5);
|
||||
printf ("Int_2_Loc: %d\n", Int_2_Loc);
|
||||
printf (" should be: %d\n", 13);
|
||||
printf ("Int_3_Loc: %d\n", Int_3_Loc);
|
||||
printf (" should be: %d\n", 7);
|
||||
printf ("Enum_Loc: %d\n", Enum_Loc);
|
||||
printf (" should be: %d\n", 1);
|
||||
printf ("Str_1_Loc: %s\n", Str_1_Loc);
|
||||
printf (" should be: DHRYSTONE PROGRAM, 1'ST STRING\n");
|
||||
printf ("Str_2_Loc: %s\n", Str_2_Loc);
|
||||
printf (" should be: DHRYSTONE PROGRAM, 2'ND STRING\n");
|
||||
printf ("\n");
|
||||
|
||||
User_Time = End_Time - Begin_Time;
|
||||
|
||||
if (User_Time < Too_Small_Time)
|
||||
{
|
||||
printf ("Measured time too small to obtain meaningful results\n");
|
||||
printf ("Please increase number of runs\n");
|
||||
printf ("\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef TIME
|
||||
Microseconds = (float) User_Time * Mic_secs_Per_Second
|
||||
/ (float) Number_Of_Runs;
|
||||
Dhrystones_Per_Second = (float) Number_Of_Runs / (float) User_Time;
|
||||
#else
|
||||
Microseconds = (float) User_Time * Mic_secs_Per_Second
|
||||
/ ((float) HZ * ((float) Number_Of_Runs));
|
||||
Dhrystones_Per_Second = ((float) HZ * (float) Number_Of_Runs)
|
||||
/ (float) User_Time;
|
||||
#endif
|
||||
printf ("Microseconds for one run through Dhrystone: ");
|
||||
printf ("%6.1f \n", Microseconds);
|
||||
printf ("Dhrystones per Second: ");
|
||||
printf ("%6.1f \n", Dhrystones_Per_Second);
|
||||
printf ("\n");
|
||||
}
|
||||
#endif /* SELF_TIMED */
|
||||
}
|
||||
|
||||
|
||||
void Proc_1 (REG Rec_Pointer Ptr_Val_Par)
|
||||
/* executed once */
|
||||
{
|
||||
REG Rec_Pointer Next_Record = Ptr_Val_Par->Ptr_Comp;
|
||||
/* == Ptr_Glob_Next */
|
||||
/* Local variable, initialized with Ptr_Val_Par->Ptr_Comp, */
|
||||
/* corresponds to "rename" in Ada, "with" in Pascal */
|
||||
|
||||
structassign (*Ptr_Val_Par->Ptr_Comp, *Ptr_Glob);
|
||||
Ptr_Val_Par->variant.var_1.Int_Comp = 5;
|
||||
Next_Record->variant.var_1.Int_Comp
|
||||
= Ptr_Val_Par->variant.var_1.Int_Comp;
|
||||
Next_Record->Ptr_Comp = Ptr_Val_Par->Ptr_Comp;
|
||||
Proc_3 (&Next_Record->Ptr_Comp);
|
||||
/* Ptr_Val_Par->Ptr_Comp->Ptr_Comp
|
||||
== Ptr_Glob->Ptr_Comp */
|
||||
if (Next_Record->Discr == Ident_1)
|
||||
/* then, executed */
|
||||
{
|
||||
Next_Record->variant.var_1.Int_Comp = 6;
|
||||
Proc_6 (Ptr_Val_Par->variant.var_1.Enum_Comp,
|
||||
&Next_Record->variant.var_1.Enum_Comp);
|
||||
Next_Record->Ptr_Comp = Ptr_Glob->Ptr_Comp;
|
||||
Proc_7 (Next_Record->variant.var_1.Int_Comp, 10,
|
||||
&Next_Record->variant.var_1.Int_Comp);
|
||||
}
|
||||
else /* not executed */
|
||||
structassign (*Ptr_Val_Par, *Ptr_Val_Par->Ptr_Comp);
|
||||
} /* Proc_1 */
|
||||
|
||||
|
||||
void Proc_2 (One_Fifty *Int_Par_Ref)
|
||||
/* executed once */
|
||||
/* *Int_Par_Ref == 1, becomes 4 */
|
||||
{
|
||||
One_Fifty Int_Loc;
|
||||
Enumeration Enum_Loc;
|
||||
|
||||
Enum_Loc = 0;
|
||||
|
||||
Int_Loc = *Int_Par_Ref + 10;
|
||||
do /* executed once */
|
||||
if (Ch_1_Glob == 'A')
|
||||
/* then, executed */
|
||||
{
|
||||
Int_Loc -= 1;
|
||||
*Int_Par_Ref = Int_Loc - Int_Glob;
|
||||
Enum_Loc = Ident_1;
|
||||
} /* if */
|
||||
while (Enum_Loc != Ident_1); /* true */
|
||||
} /* Proc_2 */
|
||||
|
||||
|
||||
void Proc_3 (Rec_Pointer *Ptr_Ref_Par)
|
||||
/* executed once */
|
||||
/* Ptr_Ref_Par becomes Ptr_Glob */
|
||||
{
|
||||
if (Ptr_Glob != Null)
|
||||
/* then, executed */
|
||||
*Ptr_Ref_Par = Ptr_Glob->Ptr_Comp;
|
||||
Proc_7 (10, Int_Glob, &Ptr_Glob->variant.var_1.Int_Comp);
|
||||
} /* Proc_3 */
|
||||
|
||||
|
||||
void Proc_4 (void) /* without parameters */
|
||||
/* executed once */
|
||||
{
|
||||
Boolean Bool_Loc;
|
||||
|
||||
Bool_Loc = Ch_1_Glob == 'A';
|
||||
Bool_Glob = Bool_Loc | Bool_Glob;
|
||||
Ch_2_Glob = 'B';
|
||||
} /* Proc_4 */
|
||||
|
||||
void Proc_5 (void) /* without parameters */
|
||||
/*******/
|
||||
/* executed once */
|
||||
{
|
||||
Ch_1_Glob = 'A';
|
||||
Bool_Glob = false;
|
||||
} /* Proc_5 */
|
||||
|
||||
|
||||
/* Procedure for the assignment of structures, */
|
||||
/* if the C compiler doesn't support this feature */
|
||||
#ifdef NOSTRUCTASSIGN
|
||||
memcpy (d, s, l)
|
||||
register char *d;
|
||||
register char *s;
|
||||
register int l;
|
||||
{
|
||||
while (l--) *d++ = *s++;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
209
UnixBench/src/dhry_2.c
Normal file
209
UnixBench/src/dhry_2.c
Normal file
@ -0,0 +1,209 @@
|
||||
/*****************************************************************************
|
||||
* The BYTE UNIX Benchmarks - Release 3
|
||||
* Module: dhry_2.c SID: 3.4 5/15/91 19:30:22
|
||||
*
|
||||
*****************************************************************************
|
||||
* Bug reports, patches, comments, suggestions should be sent to:
|
||||
*
|
||||
* Ben Smith, Rick Grehan or Tom Yager
|
||||
* ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
|
||||
*
|
||||
*****************************************************************************
|
||||
* Modification Log:
|
||||
* 10/22/97 - code cleanup to remove ANSI C compiler warnings
|
||||
* Andy Kahn <kahn@zk3.dec.com>
|
||||
*
|
||||
* Adapted from:
|
||||
*
|
||||
* "DHRYSTONE" Benchmark Program
|
||||
* -----------------------------
|
||||
*
|
||||
* **** WARNING **** See warning in n.dhry_1.c
|
||||
*
|
||||
* Version: C, Version 2.1
|
||||
*
|
||||
* File: dhry_2.c (part 3 of 3)
|
||||
*
|
||||
* Date: May 25, 1988
|
||||
*
|
||||
* Author: Reinhold P. Weicker
|
||||
*
|
||||
****************************************************************************/
|
||||
/* SCCSid is defined in dhry_1.c */
|
||||
|
||||
#include <string.h>
|
||||
#include "dhry.h"
|
||||
|
||||
#ifndef REG
|
||||
#define REG
|
||||
/* REG becomes defined as empty */
|
||||
/* i.e. no register variables */
|
||||
#endif
|
||||
|
||||
extern int Int_Glob;
|
||||
extern char Ch_1_Glob;
|
||||
|
||||
void Proc_6(Enumeration, Enumeration *);
|
||||
void Proc_7(One_Fifty, One_Fifty, One_Fifty *);
|
||||
void Proc_8(Arr_1_Dim, Arr_2_Dim, int, int);
|
||||
Enumeration Func_1(Capital_Letter, Capital_Letter);
|
||||
Boolean Func_2(Str_30, Str_30);
|
||||
Boolean Func_3(Enumeration);
|
||||
|
||||
void Proc_6 (Enumeration Enum_Val_Par, Enumeration *Enum_Ref_Par)
|
||||
/* executed once */
|
||||
/* Enum_Val_Par == Ident_3, Enum_Ref_Par becomes Ident_2 */
|
||||
{
|
||||
*Enum_Ref_Par = Enum_Val_Par;
|
||||
if (! Func_3 (Enum_Val_Par))
|
||||
/* then, not executed */
|
||||
*Enum_Ref_Par = Ident_4;
|
||||
switch (Enum_Val_Par)
|
||||
{
|
||||
case Ident_1:
|
||||
*Enum_Ref_Par = Ident_1;
|
||||
break;
|
||||
case Ident_2:
|
||||
if (Int_Glob > 100)
|
||||
/* then */
|
||||
*Enum_Ref_Par = Ident_1;
|
||||
else *Enum_Ref_Par = Ident_4;
|
||||
break;
|
||||
case Ident_3: /* executed */
|
||||
*Enum_Ref_Par = Ident_2;
|
||||
break;
|
||||
case Ident_4: break;
|
||||
case Ident_5:
|
||||
*Enum_Ref_Par = Ident_3;
|
||||
break;
|
||||
} /* switch */
|
||||
} /* Proc_6 */
|
||||
|
||||
void Proc_7 (Int_1_Par_Val, Int_2_Par_Val, Int_Par_Ref)
|
||||
One_Fifty Int_1_Par_Val;
|
||||
One_Fifty Int_2_Par_Val;
|
||||
One_Fifty *Int_Par_Ref;
|
||||
/**********************************************/
|
||||
/* executed three times */
|
||||
/* first call: Int_1_Par_Val == 2, Int_2_Par_Val == 3, */
|
||||
/* Int_Par_Ref becomes 7 */
|
||||
/* second call: Int_1_Par_Val == 10, Int_2_Par_Val == 5, */
|
||||
/* Int_Par_Ref becomes 17 */
|
||||
/* third call: Int_1_Par_Val == 6, Int_2_Par_Val == 10, */
|
||||
/* Int_Par_Ref becomes 18 */
|
||||
{
|
||||
One_Fifty Int_Loc;
|
||||
|
||||
Int_Loc = Int_1_Par_Val + 2;
|
||||
*Int_Par_Ref = Int_2_Par_Val + Int_Loc;
|
||||
} /* Proc_7 */
|
||||
|
||||
|
||||
void Proc_8 (Arr_1_Par_Ref, Arr_2_Par_Ref, Int_1_Par_Val, Int_2_Par_Val)
|
||||
/*********************************************************************/
|
||||
/* executed once */
|
||||
/* Int_Par_Val_1 == 3 */
|
||||
/* Int_Par_Val_2 == 7 */
|
||||
Arr_1_Dim Arr_1_Par_Ref;
|
||||
Arr_2_Dim Arr_2_Par_Ref;
|
||||
int Int_1_Par_Val;
|
||||
int Int_2_Par_Val;
|
||||
{
|
||||
REG One_Fifty Int_Index;
|
||||
REG One_Fifty Int_Loc;
|
||||
|
||||
Int_Loc = Int_1_Par_Val + 5;
|
||||
Arr_1_Par_Ref [Int_Loc] = Int_2_Par_Val;
|
||||
Arr_1_Par_Ref [Int_Loc+1] = Arr_1_Par_Ref [Int_Loc];
|
||||
Arr_1_Par_Ref [Int_Loc+30] = Int_Loc;
|
||||
for (Int_Index = Int_Loc; Int_Index <= Int_Loc+1; ++Int_Index)
|
||||
Arr_2_Par_Ref [Int_Loc] [Int_Index] = Int_Loc;
|
||||
Arr_2_Par_Ref [Int_Loc] [Int_Loc-1] += 1;
|
||||
Arr_2_Par_Ref [Int_Loc+20] [Int_Loc] = Arr_1_Par_Ref [Int_Loc];
|
||||
Int_Glob = 5;
|
||||
} /* Proc_8 */
|
||||
|
||||
|
||||
Enumeration Func_1 (Capital_Letter Ch_1_Par_Val, Capital_Letter Ch_2_Par_Val)
|
||||
/*************************************************/
|
||||
/* executed three times */
|
||||
/* first call: Ch_1_Par_Val == 'H', Ch_2_Par_Val == 'R' */
|
||||
/* second call: Ch_1_Par_Val == 'A', Ch_2_Par_Val == 'C' */
|
||||
/* third call: Ch_1_Par_Val == 'B', Ch_2_Par_Val == 'C' */
|
||||
{
|
||||
Capital_Letter Ch_1_Loc;
|
||||
Capital_Letter Ch_2_Loc;
|
||||
|
||||
Ch_1_Loc = Ch_1_Par_Val;
|
||||
Ch_2_Loc = Ch_1_Loc;
|
||||
if (Ch_2_Loc != Ch_2_Par_Val)
|
||||
/* then, executed */
|
||||
return (Ident_1);
|
||||
else /* not executed */
|
||||
{
|
||||
Ch_1_Glob = Ch_1_Loc;
|
||||
return (Ident_2);
|
||||
}
|
||||
} /* Func_1 */
|
||||
|
||||
|
||||
|
||||
Boolean Func_2 (Str_1_Par_Ref, Str_2_Par_Ref)
|
||||
/*************************************************/
|
||||
/* executed once */
|
||||
/* Str_1_Par_Ref == "DHRYSTONE PROGRAM, 1'ST STRING" */
|
||||
/* Str_2_Par_Ref == "DHRYSTONE PROGRAM, 2'ND STRING" */
|
||||
|
||||
Str_30 Str_1_Par_Ref;
|
||||
Str_30 Str_2_Par_Ref;
|
||||
{
|
||||
REG One_Thirty Int_Loc;
|
||||
Capital_Letter Ch_Loc;
|
||||
|
||||
Ch_Loc = 'A';
|
||||
Int_Loc = 2;
|
||||
while (Int_Loc <= 2) /* loop body executed once */
|
||||
if (Func_1 (Str_1_Par_Ref[Int_Loc],
|
||||
Str_2_Par_Ref[Int_Loc+1]) == Ident_1)
|
||||
/* then, executed */
|
||||
{
|
||||
Ch_Loc = 'A';
|
||||
Int_Loc += 1;
|
||||
} /* if, while */
|
||||
if (Ch_Loc >= 'W' && Ch_Loc < 'Z')
|
||||
/* then, not executed */
|
||||
Int_Loc = 7;
|
||||
if (Ch_Loc == 'R')
|
||||
/* then, not executed */
|
||||
return (true);
|
||||
else /* executed */
|
||||
{
|
||||
if (strcmp (Str_1_Par_Ref, Str_2_Par_Ref) > 0)
|
||||
/* then, not executed */
|
||||
{
|
||||
Int_Loc += 7;
|
||||
Int_Glob = Int_Loc;
|
||||
return (true);
|
||||
}
|
||||
else /* executed */
|
||||
return (false);
|
||||
} /* if Ch_Loc */
|
||||
} /* Func_2 */
|
||||
|
||||
|
||||
Boolean Func_3 (Enum_Par_Val)
|
||||
/***************************/
|
||||
/* executed once */
|
||||
/* Enum_Par_Val == Ident_3 */
|
||||
Enumeration Enum_Par_Val;
|
||||
{
|
||||
Enumeration Enum_Loc;
|
||||
|
||||
Enum_Loc = Enum_Par_Val;
|
||||
if (Enum_Loc == Ident_3)
|
||||
/* then, executed */
|
||||
return (true);
|
||||
else /* not executed */
|
||||
return (false);
|
||||
} /* Func_3 */
|
||||
|
319
UnixBench/src/dummy.c
Normal file
319
UnixBench/src/dummy.c
Normal file
@ -0,0 +1,319 @@
|
||||
/*******************************************************************************
|
||||
* The BYTE UNIX Benchmarks - Release 3
|
||||
* Module: dummy.c SID: 3.3 5/15/91 19:30:19
|
||||
*
|
||||
*******************************************************************************
|
||||
* Bug reports, patches, comments, suggestions should be sent to:
|
||||
*
|
||||
* Ben Smith, Rick Grehan or Tom Yager
|
||||
* ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
|
||||
*
|
||||
*******************************************************************************
|
||||
* Modification Log:
|
||||
* 10/22/97 - code cleanup to remove ANSI C compiler warnings
|
||||
* Andy Kahn <kahn@zk3.dec.com>
|
||||
*
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Hacked up C program for use in the standard shell.? scripts of
|
||||
* the multiuser test. This is based upon makework.c, and is typically
|
||||
* edited using edscript.2 before compilation.
|
||||
*
|
||||
* $Header: dummy.c,v 3.4 87/06/23 15:54:53 kjmcdonell Beta $
|
||||
*/
|
||||
char SCCSid[] = "@(#) @(#)dummy.c:3.3 -- 5/15/91 19:30:19";
|
||||
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
|
||||
#define DEF_RATE 5.0
|
||||
#define GRANULE 5
|
||||
#define CHUNK 60
|
||||
#define MAXCHILD 12
|
||||
#define MAXWORK 10
|
||||
|
||||
float thres;
|
||||
float est_rate = DEF_RATE;
|
||||
int nusers; /* number of concurrent users to be simulated by
|
||||
* this process */
|
||||
int firstuser; /* ordinal identification of first user for this
|
||||
* process */
|
||||
int nwork = 0; /* number of job streams */
|
||||
int exit_status = 0; /* returned to parent */
|
||||
int sigpipe; /* pipe write error flag */
|
||||
|
||||
struct st_work {
|
||||
char *cmd; /* name of command to run */
|
||||
char **av; /* arguments to command */
|
||||
char *input; /* standard input buffer */
|
||||
int inpsize; /* size of standard input buffer */
|
||||
} work[MAXWORK];
|
||||
|
||||
struct {
|
||||
int xmit; /* # characters sent */
|
||||
char *bp; /* std input buffer pointer */
|
||||
int blen; /* std input buffer length */
|
||||
int fd; /* stdin to command */
|
||||
int pid; /* child PID */
|
||||
char *line; /* start of input line */
|
||||
int firstjob; /* inital piece of work */
|
||||
int thisjob; /* current piece of work */
|
||||
} child[MAXCHILD], *cp;
|
||||
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
int i;
|
||||
int l;
|
||||
int fcopy = 0; /* fd for copy output */
|
||||
int master = 1; /* the REAL master, == 0 for clones */
|
||||
int nchild; /* no. of children for a clone to run */
|
||||
int done; /* count of children finished */
|
||||
int output; /* aggregate output char count for all
|
||||
children */
|
||||
int c;
|
||||
int thiswork = 0; /* next job stream to allocate */
|
||||
int nch; /* # characters to write */
|
||||
int written; /* # characters actully written */
|
||||
char logname[15]; /* name of the log file(s) */
|
||||
void onalarm(void);
|
||||
void pipeerr(void);
|
||||
void wrapup(void);
|
||||
void grunt(void);
|
||||
char *malloc();
|
||||
int pvec[2]; /* for pipes */
|
||||
char *p;
|
||||
char *prog; /* my name */
|
||||
|
||||
#if ! debug
|
||||
freopen("masterlog.00", "a", stderr);
|
||||
#endif
|
||||
fprintf(stderr, "*** New Run *** ");
|
||||
prog = argv[0];
|
||||
while (argc > 1 && argv[1][0] == '-') {
|
||||
p = &argv[1][1];
|
||||
argc--;
|
||||
argv++;
|
||||
while (*p) {
|
||||
switch (*p) {
|
||||
case 'r':
|
||||
/* code DELETED here */
|
||||
argc--;
|
||||
argv++;
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
/* code DELETED here */
|
||||
lseek(fcopy, 0L, 2); /* append at end of file */
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "%s: bad flag '%c'\n", prog, *p);
|
||||
exit(4);
|
||||
}
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "%s: missing nusers\n", prog);
|
||||
exit(4);
|
||||
}
|
||||
|
||||
nusers = atoi(argv[1]);
|
||||
if (nusers < 1) {
|
||||
fprintf(stderr, "%s: impossible nusers (%d<-%s)\n", prog, nusers, argv[1]);
|
||||
exit(4);
|
||||
}
|
||||
fprintf(stderr, "%d Users\n", nusers);
|
||||
argc--;
|
||||
argv++;
|
||||
|
||||
/* build job streams */
|
||||
getwork();
|
||||
#if debug
|
||||
dumpwork();
|
||||
#endif
|
||||
|
||||
/* clone copies of myself to run up to MAXCHILD jobs each */
|
||||
firstuser = MAXCHILD;
|
||||
fprintf(stderr, "master pid %d\n", getpid());
|
||||
fflush(stderr);
|
||||
while (nusers > MAXCHILD) {
|
||||
fflush(stderr);
|
||||
if (nusers >= 2*MAXCHILD)
|
||||
/* the next clone must run MAXCHILD jobs */
|
||||
nchild = MAXCHILD;
|
||||
else
|
||||
/* the next clone must run the leftover jobs */
|
||||
nchild = nusers - MAXCHILD;
|
||||
if ((l = fork()) == -1) {
|
||||
/* fork failed */
|
||||
fatal("** clone fork failed **\n");
|
||||
goto bepatient;
|
||||
} else if (l > 0) {
|
||||
fprintf(stderr, "master clone pid %d\n", l);
|
||||
/* I am the master with nchild fewer jobs to run */
|
||||
nusers -= nchild;
|
||||
firstuser += MAXCHILD;
|
||||
continue;
|
||||
} else {
|
||||
/* I am a clone, run MAXCHILD jobs */
|
||||
#if ! debug
|
||||
sprintf(logname, "masterlog.%02d", firstuser/MAXCHILD);
|
||||
freopen(logname, "w", stderr);
|
||||
#endif
|
||||
master = 0;
|
||||
nusers = nchild;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (master)
|
||||
firstuser = 0;
|
||||
|
||||
close(0);
|
||||
|
||||
/* code DELETED here */
|
||||
|
||||
fflush(stderr);
|
||||
|
||||
srand(time(0));
|
||||
thres = 0;
|
||||
done = output = 0;
|
||||
for (i = 0; i < nusers; i++) {
|
||||
if (child[i].blen == 0)
|
||||
done++;
|
||||
else
|
||||
thres += est_rate * GRANULE;
|
||||
}
|
||||
est_rate = thres;
|
||||
|
||||
signal(SIGALRM, onalarm);
|
||||
signal(SIGPIPE, pipeerr);
|
||||
alarm(GRANULE);
|
||||
while (done < nusers) {
|
||||
for (i = 0; i < nusers; i++) {
|
||||
cp = &child[i];
|
||||
if (cp->xmit >= cp->blen) continue;
|
||||
l = rand() % CHUNK + 1; /* 1-CHUNK chars */
|
||||
if (l == 0) continue;
|
||||
if (cp->xmit + l > cp->blen)
|
||||
l = cp->blen - cp->xmit;
|
||||
p = cp->bp;
|
||||
cp->bp += l;
|
||||
cp->xmit += l;
|
||||
#if debug
|
||||
fprintf(stderr, "child %d, %d processed, %d to go\n", i, cp->xmit, cp->blen - cp->xmit);
|
||||
#endif
|
||||
while (p < cp->bp) {
|
||||
if (*p == '\n' || (p == &cp->bp[-1] && cp->xmit >= cp->blen)) {
|
||||
/* write it out */
|
||||
nch = p - cp->line + 1;
|
||||
if ((written = write(cp->fd, cp->line, nch)) != nch) {
|
||||
|
||||
/* code DELETED here */
|
||||
|
||||
}
|
||||
if (fcopy)
|
||||
write(fcopy, cp->line, p - cp->line + 1);
|
||||
#if debug
|
||||
fprintf(stderr, "child %d gets \"", i);
|
||||
{
|
||||
char *q = cp->line;
|
||||
while (q <= p) {
|
||||
if (*q >= ' ' && *q <= '~')
|
||||
fputc(*q, stderr);
|
||||
else
|
||||
fprintf(stderr, "\\%03o", *q);
|
||||
q++;
|
||||
}
|
||||
}
|
||||
fputc('"', stderr);
|
||||
#endif
|
||||
cp->line = &p[1];
|
||||
}
|
||||
p++;
|
||||
}
|
||||
if (cp->xmit >= cp->blen) {
|
||||
done++;
|
||||
close(cp->fd);
|
||||
#if debug
|
||||
fprintf(stderr, "child %d, close std input\n", i);
|
||||
#endif
|
||||
}
|
||||
output += l;
|
||||
}
|
||||
while (output > thres) {
|
||||
pause();
|
||||
#if debug
|
||||
fprintf(stderr, "after pause: output, thres, done %d %.2f %d\n", output, thres, done);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
bepatient:
|
||||
alarm(0);
|
||||
/****
|
||||
* If everything is going OK, we should simply be able to keep
|
||||
* looping unitil 'wait' fails, however some descendent process may
|
||||
* be in a state from which it can never exit, and so a timeout
|
||||
* is used.
|
||||
* 5 minutes should be ample, since the time to run all jobs is of
|
||||
* the order of 5-10 minutes, however some machines are painfully slow,
|
||||
* so the timeout has been set at 20 minutes (1200 seconds).
|
||||
****/
|
||||
|
||||
/* code DELETED here */
|
||||
|
||||
}
|
||||
|
||||
onalarm()
|
||||
{
|
||||
thres += est_rate;
|
||||
signal(SIGALRM, onalarm);
|
||||
alarm(GRANULE);
|
||||
}
|
||||
|
||||
grunt()
|
||||
{
|
||||
/* timeout after label "bepatient" in main */
|
||||
exit_status = 4;
|
||||
wrapup();
|
||||
}
|
||||
|
||||
pipeerr()
|
||||
{
|
||||
sigpipe++;
|
||||
}
|
||||
|
||||
wrapup()
|
||||
{
|
||||
/* DUMMY, real code dropped */
|
||||
}
|
||||
|
||||
getwork()
|
||||
{
|
||||
|
||||
/* DUMMY, real code dropped */
|
||||
gets();
|
||||
strncpy();
|
||||
malloc(); realloc();
|
||||
open(); close();
|
||||
}
|
||||
|
||||
fatal(s)
|
||||
char *s;
|
||||
{
|
||||
int i;
|
||||
fprintf(stderr, s);
|
||||
fflush(stderr);
|
||||
perror("Reason?");
|
||||
for (i = 0; i < nusers; i++) {
|
||||
if (child[i].pid > 0 && kill(child[i].pid, SIGKILL) != -1)
|
||||
fprintf(stderr, "pid %d killed off\n", child[i].pid);
|
||||
}
|
||||
fflush(stderr);
|
||||
exit_status = 4;
|
||||
return;
|
||||
}
|
97
UnixBench/src/execl.c
Normal file
97
UnixBench/src/execl.c
Normal file
@ -0,0 +1,97 @@
|
||||
/*******************************************************************************
|
||||
* The BYTE UNIX Benchmarks - Release 3
|
||||
* Module: execl.c SID: 3.3 5/15/91 19:30:19
|
||||
*
|
||||
*******************************************************************************
|
||||
* Bug reports, patches, comments, suggestions should be sent to:
|
||||
*
|
||||
* Ben Smith, Rick Grehan or Tom Yager
|
||||
* ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
|
||||
*
|
||||
*******************************************************************************
|
||||
* Modification Log:
|
||||
* $Header: execl.c,v 3.5 87/06/22 15:37:08 kjmcdonell Beta $
|
||||
* August 28, 1990 - Modified timing routines
|
||||
* October 22, 1997 - code cleanup to remove ANSI C compiler warnings
|
||||
* Andy Kahn <kahn@zk3.dec.com>
|
||||
*
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Execing
|
||||
*
|
||||
*/
|
||||
char SCCSid[] = "@(#) @(#)execl.c:3.3 -- 5/15/91 19:30:19";
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
char bss[8*1024]; /* something worthwhile */
|
||||
|
||||
#define main dummy
|
||||
|
||||
#include "big.c" /* some real code */
|
||||
|
||||
#undef main
|
||||
|
||||
/* added by BYTE */
|
||||
char *getenv();
|
||||
|
||||
|
||||
int main(argc, argv) /* the real program */
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
unsigned long iter = 0;
|
||||
char *ptr;
|
||||
char *fullpath;
|
||||
int duration;
|
||||
char count_str[12], start_str[24], path_str[256], *dur_str;
|
||||
time_t start_time, this_time;
|
||||
|
||||
#ifdef DEBUG
|
||||
int count;
|
||||
for(count = 0; count < argc; ++ count)
|
||||
printf("%s ",argv[count]);
|
||||
printf("\n");
|
||||
#endif
|
||||
if (argc < 2)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s duration\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
duration = atoi(argv[1]);
|
||||
if (duration > 0)
|
||||
/* the first invocation */
|
||||
{
|
||||
dur_str = argv[1];
|
||||
if((ptr = getenv("UB_BINDIR")) != NULL)
|
||||
sprintf(path_str,"%s/execl",ptr);
|
||||
fullpath=path_str;
|
||||
time(&start_time);
|
||||
}
|
||||
else /* one of those execl'd invocations */
|
||||
{
|
||||
/* real duration follow the phoney null duration */
|
||||
duration = atoi(argv[2]);
|
||||
dur_str = argv[2];
|
||||
iter = (unsigned long)atoi(argv[3]); /* where are we now ? */
|
||||
sscanf(argv[4], "%lu", (unsigned long *) &start_time);
|
||||
fullpath = argv[0];
|
||||
}
|
||||
|
||||
sprintf(count_str, "%lu", ++iter); /* increment the execl counter */
|
||||
sprintf(start_str, "%lu", (unsigned long) start_time);
|
||||
time(&this_time);
|
||||
if (this_time - start_time >= duration) { /* time has run out */
|
||||
fprintf(stderr, "COUNT|%lu|1|lps\n", iter);
|
||||
exit(0);
|
||||
}
|
||||
execl(fullpath, fullpath, "0", dur_str, count_str, start_str, (void *) 0);
|
||||
fprintf(stderr, "Exec failed at iteration %lu\n", iter);
|
||||
perror("Reason");
|
||||
exit(1);
|
||||
}
|
469
UnixBench/src/fstime.c
Normal file
469
UnixBench/src/fstime.c
Normal file
@ -0,0 +1,469 @@
|
||||
/*******************************************************************************
|
||||
* The BYTE UNIX Benchmarks - Release 3
|
||||
* Module: fstime.c SID: 3.5 5/15/91 19:30:19
|
||||
*
|
||||
*******************************************************************************
|
||||
* Bug reports, patches, comments, suggestions should be sent to:
|
||||
*
|
||||
* Ben Smith, Rick Grehan or Tom Yager
|
||||
* ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
|
||||
*
|
||||
*******************************************************************************
|
||||
* Modification Log:
|
||||
* $Header: fstime.c,v 3.4 87/06/22 14:23:05 kjmcdonell Beta $
|
||||
* 10/19/89 - rewrote timing calcs and added clock check (Ben Smith)
|
||||
* 10/26/90 - simplify timing, change defaults (Tom Yager)
|
||||
* 11/16/90 - added better error handling and changed output format (Ben Smith)
|
||||
* 11/17/90 - changed the whole thing around (Ben Smith)
|
||||
* 2/22/91 - change a few style elements and improved error handling (Ben Smith)
|
||||
* 4/17/91 - incorporated suggestions from Seckin Unlu (seckin@sumac.intel.com)
|
||||
* 4/17/91 - limited size of file, will rewind when reaches end of file
|
||||
* 7/95 - fixed mishandling of read() and write() return codes
|
||||
* Carl Emilio Prelz <fluido@telepac.pt>
|
||||
* 12/95 - Massive changes. Made sleep time proportional increase with run
|
||||
* time; added fsbuffer and fsdisk variants; added partial counting
|
||||
* of partial reads/writes (was *full* credit); added dual syncs.
|
||||
* David C Niemi <niemi@tux.org>
|
||||
* 10/22/97 - code cleanup to remove ANSI C compiler warnings
|
||||
* Andy Kahn <kahn@zk3.dec.com>
|
||||
* 9/24/07 - Separate out the read and write tests;
|
||||
* output the actual time used in the results.
|
||||
* Ian Smith <johantheghost at yahoo period com>
|
||||
******************************************************************************/
|
||||
char SCCSid[] = "@(#) @(#)fstime.c:3.5 -- 5/15/91 19:30:19";
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#define SECONDS 10
|
||||
|
||||
#define MAX_BUFSIZE 8192
|
||||
|
||||
/* This must be set to the smallest BUFSIZE or 1024, whichever is smaller */
|
||||
#define COUNTSIZE 256
|
||||
#define HALFCOUNT (COUNTSIZE/2) /* Half of COUNTSIZE */
|
||||
|
||||
#define FNAME0 "dummy0"
|
||||
#define FNAME1 "dummy1"
|
||||
|
||||
extern void sync(void);
|
||||
|
||||
int w_test(int timeSecs);
|
||||
int r_test(int timeSecs);
|
||||
int c_test(int timeSecs);
|
||||
|
||||
long read_score = 1, write_score = 1, copy_score = 1;
|
||||
|
||||
/****************** GLOBALS ***************************/
|
||||
|
||||
/* The buffer size for the tests. */
|
||||
int bufsize = 1024;
|
||||
|
||||
/*
|
||||
* The max number of 1024-byte blocks in the file.
|
||||
* Don't limit it much, so that memory buffering
|
||||
* can be overcome.
|
||||
*/
|
||||
int max_blocks = 2000;
|
||||
|
||||
/* The max number of BUFSIZE blocks in the file. */
|
||||
int max_buffs = 2000;
|
||||
|
||||
/* Countable units per 1024 bytes */
|
||||
int count_per_k;
|
||||
|
||||
/* Countable units per bufsize */
|
||||
int count_per_buf;
|
||||
|
||||
/* The actual buffer. */
|
||||
/* char *buf = 0; */
|
||||
/* Let's carry on using a static buffer for this, like older versions
|
||||
* of the code did. It turns out that if you use a malloc buffer,
|
||||
* it goes 50% slower on reads, when using a 4k buffer -- at least on
|
||||
* my OpenSUSE 10.2 system.
|
||||
* What up wit dat?
|
||||
*/
|
||||
char buf[MAX_BUFSIZE];
|
||||
|
||||
int f;
|
||||
int g;
|
||||
int i;
|
||||
void stop_count();
|
||||
void clean_up();
|
||||
int sigalarm = 0;
|
||||
|
||||
/******************** MAIN ****************************/
|
||||
|
||||
int main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
/* The number of seconds to run for. */
|
||||
int seconds = SECONDS;
|
||||
|
||||
/* The type of test to run. */
|
||||
char test = 'c';
|
||||
|
||||
int status;
|
||||
int i;
|
||||
|
||||
for (i = 1; i < argc; ++i) {
|
||||
if (argv[i][0] == '-') {
|
||||
switch (argv[i][1]) {
|
||||
case 'c':
|
||||
case 'r':
|
||||
case 'w':
|
||||
test = argv[i][1];
|
||||
break;
|
||||
case 'b':
|
||||
bufsize = atoi(argv[++i]);
|
||||
break;
|
||||
case 'm':
|
||||
max_blocks = atoi(argv[++i]);
|
||||
break;
|
||||
case 't':
|
||||
seconds = atoi(argv[++i]);
|
||||
break;
|
||||
case 'd':
|
||||
if (chdir(argv[++i]) < 0) {
|
||||
perror("fstime: chdir");
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Usage: fstime [-c|-r|-w] [-b <bufsize>] [-m <max_blocks>] [-t <seconds>]\n");
|
||||
exit(2);
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "Usage: fstime [-c|-r|-w] [-b <bufsize>] [-m <max_blocks>] [-t <seconds>]\n");
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
|
||||
if (bufsize < COUNTSIZE || bufsize > MAX_BUFSIZE) {
|
||||
fprintf(stderr, "fstime: buffer size must be in range %d-%d\n",
|
||||
COUNTSIZE, 1024*1024);
|
||||
exit(3);
|
||||
}
|
||||
if (max_blocks < 1 || max_blocks > 1024*1024) {
|
||||
fprintf(stderr, "fstime: max blocks must be in range %d-%d\n",
|
||||
1, 1024*1024);
|
||||
exit(3);
|
||||
}
|
||||
if (seconds < 1 || seconds > 3600) {
|
||||
fprintf(stderr, "fstime: time must be in range %d-%d seconds\n",
|
||||
1, 3600);
|
||||
exit(3);
|
||||
}
|
||||
|
||||
max_buffs = max_blocks * 1024 / bufsize;
|
||||
count_per_k = 1024 / COUNTSIZE;
|
||||
count_per_buf = bufsize / COUNTSIZE;
|
||||
|
||||
/*
|
||||
if ((buf = malloc(bufsize)) == 0) {
|
||||
fprintf(stderr, "fstime: failed to malloc %d bytes\n", bufsize);
|
||||
exit(4);
|
||||
}
|
||||
*/
|
||||
|
||||
if((f = creat(FNAME0, 0600)) == -1) {
|
||||
perror("fstime: creat");
|
||||
exit(1);
|
||||
}
|
||||
close(f);
|
||||
|
||||
if((g = creat(FNAME1, 0600)) == -1) {
|
||||
perror("fstime: creat");
|
||||
exit(1);
|
||||
}
|
||||
close(g);
|
||||
|
||||
if( (f = open(FNAME0, 2)) == -1) {
|
||||
perror("fstime: open");
|
||||
exit(1);
|
||||
}
|
||||
if( ( g = open(FNAME1, 2)) == -1 ) {
|
||||
perror("fstime: open");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* fill buffer */
|
||||
for (i=0; i < bufsize; ++i)
|
||||
buf[i] = i & 0xff;
|
||||
|
||||
signal(SIGKILL,clean_up);
|
||||
|
||||
/*
|
||||
* Run the selected test.
|
||||
* When I got here, this program ran full 30-second tests for
|
||||
* write, read, and copy, outputting the results for each. BUT
|
||||
* only the copy results are actually used in the benchmark index.
|
||||
* With multiple iterations and three sets of FS tests, that amounted
|
||||
* to about 10 minutes of wasted time per run.
|
||||
*
|
||||
* So, I've made the test selectable. Except that the read and write
|
||||
* passes are used to create the test file and calibrate the rates used
|
||||
* to tweak the results of the copy test. So, for copy tests, we do
|
||||
* a few seconds of write and read to prime the pump.
|
||||
*
|
||||
* Note that this will also pull the file into the FS cache on any
|
||||
* modern system prior to the copy test. Whether this is good or
|
||||
* bad is a matter of perspective, but it's how it was when I got
|
||||
* here.
|
||||
*
|
||||
* Ian Smith <johantheghost at yahoo period com> 21 Sep 2007
|
||||
*/
|
||||
switch (test) {
|
||||
case 'w':
|
||||
status = w_test(seconds);
|
||||
break;
|
||||
case 'r':
|
||||
w_test(2);
|
||||
status = r_test(seconds);
|
||||
break;
|
||||
case 'c':
|
||||
w_test(2);
|
||||
r_test(2);
|
||||
status = c_test(seconds);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "fstime: unknown test \'%c\'\n", test);
|
||||
exit(6);
|
||||
}
|
||||
if (status) {
|
||||
clean_up();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
clean_up();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
static double getFloatTime()
|
||||
{
|
||||
struct timeval t;
|
||||
|
||||
gettimeofday(&t, 0);
|
||||
return (double) t.tv_sec + (double) t.tv_usec / 1000000.0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Run the write test for the time given in seconds.
|
||||
*/
|
||||
int w_test(int timeSecs)
|
||||
{
|
||||
unsigned long counted = 0L;
|
||||
unsigned long tmp;
|
||||
long f_blocks;
|
||||
double start, end;
|
||||
extern int sigalarm;
|
||||
|
||||
/* Sync and let it settle */
|
||||
sync();
|
||||
sleep(2);
|
||||
sync();
|
||||
sleep(2);
|
||||
|
||||
/* Set an alarm. */
|
||||
sigalarm = 0;
|
||||
signal(SIGALRM, stop_count);
|
||||
alarm(timeSecs);
|
||||
|
||||
start = getFloatTime();
|
||||
|
||||
while (!sigalarm) {
|
||||
for(f_blocks=0; f_blocks < max_buffs; ++f_blocks) {
|
||||
if ((tmp=write(f, buf, bufsize)) != bufsize) {
|
||||
if (errno != EINTR) {
|
||||
perror("fstime: write");
|
||||
return(-1);
|
||||
}
|
||||
stop_count();
|
||||
counted += ((tmp+HALFCOUNT)/COUNTSIZE);
|
||||
} else
|
||||
counted += count_per_buf;
|
||||
}
|
||||
lseek(f, 0L, 0); /* rewind */
|
||||
}
|
||||
|
||||
/* stop clock */
|
||||
end = getFloatTime();
|
||||
write_score = (long) ((double) counted / ((end - start) * count_per_k));
|
||||
printf("Write done: %ld in %.4f, score %ld\n",
|
||||
counted, end - start, write_score);
|
||||
|
||||
/*
|
||||
* Output the test results. Use the true time.
|
||||
*/
|
||||
fprintf(stderr, "COUNT|%ld|0|KBps\n", write_score);
|
||||
fprintf(stderr, "TIME|%.1f\n", end - start);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Run the read test for the time given in seconds.
|
||||
*/
|
||||
int r_test(int timeSecs)
|
||||
{
|
||||
unsigned long counted = 0L;
|
||||
unsigned long tmp;
|
||||
double start, end;
|
||||
extern int sigalarm;
|
||||
extern int errno;
|
||||
|
||||
/* Sync and let it settle */
|
||||
sync();
|
||||
sleep(2);
|
||||
sync();
|
||||
sleep(2);
|
||||
|
||||
/* rewind */
|
||||
errno = 0;
|
||||
lseek(f, 0L, 0);
|
||||
|
||||
/* Set an alarm. */
|
||||
sigalarm = 0;
|
||||
signal(SIGALRM, stop_count);
|
||||
alarm(timeSecs);
|
||||
|
||||
start = getFloatTime();
|
||||
|
||||
while (!sigalarm) {
|
||||
/* read while checking for an error */
|
||||
if ((tmp=read(f, buf, bufsize)) != bufsize) {
|
||||
switch(errno) {
|
||||
case 0:
|
||||
case EINVAL:
|
||||
lseek(f, 0L, 0); /* rewind at end of file */
|
||||
counted += (tmp+HALFCOUNT)/COUNTSIZE;
|
||||
continue;
|
||||
case EINTR:
|
||||
stop_count();
|
||||
counted += (tmp+HALFCOUNT)/COUNTSIZE;
|
||||
break;
|
||||
default:
|
||||
perror("fstime: read");
|
||||
return(-1);
|
||||
break;
|
||||
}
|
||||
} else
|
||||
counted += count_per_buf;
|
||||
}
|
||||
|
||||
/* stop clock */
|
||||
end = getFloatTime();
|
||||
read_score = (long) ((double) counted / ((end - start) * count_per_k));
|
||||
printf("Read done: %ld in %.4f, score %ld\n",
|
||||
counted, end - start, read_score);
|
||||
|
||||
/*
|
||||
* Output the test results. Use the true time.
|
||||
*/
|
||||
fprintf(stderr, "COUNT|%ld|0|KBps\n", read_score);
|
||||
fprintf(stderr, "TIME|%.1f\n", end - start);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Run the copy test for the time given in seconds.
|
||||
*/
|
||||
int c_test(int timeSecs)
|
||||
{
|
||||
unsigned long counted = 0L;
|
||||
unsigned long tmp;
|
||||
double start, end;
|
||||
extern int sigalarm;
|
||||
|
||||
sync();
|
||||
sleep(2);
|
||||
sync();
|
||||
sleep(1);
|
||||
|
||||
/* rewind */
|
||||
errno = 0;
|
||||
lseek(f, 0L, 0);
|
||||
|
||||
/* Set an alarm. */
|
||||
sigalarm = 0;
|
||||
signal(SIGALRM, stop_count);
|
||||
alarm(timeSecs);
|
||||
|
||||
start = getFloatTime();
|
||||
|
||||
while (!sigalarm) {
|
||||
if ((tmp=read(f, buf, bufsize)) != bufsize) {
|
||||
switch(errno) {
|
||||
case 0:
|
||||
case EINVAL:
|
||||
lseek(f, 0L, 0); /* rewind at end of file */
|
||||
lseek(g, 0L, 0); /* rewind the output too */
|
||||
continue;
|
||||
case EINTR:
|
||||
/* part credit for leftover bytes read */
|
||||
counted += ( (tmp * write_score) /
|
||||
(read_score + write_score)
|
||||
+ HALFCOUNT) / COUNTSIZE;
|
||||
stop_count();
|
||||
break;
|
||||
default:
|
||||
perror("fstime: copy read");
|
||||
return(-1);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if ((tmp=write(g, buf, bufsize)) != bufsize) {
|
||||
if (errno != EINTR) {
|
||||
perror("fstime: copy write");
|
||||
return(-1);
|
||||
}
|
||||
counted += (
|
||||
/* Full credit for part of buffer written */
|
||||
tmp +
|
||||
|
||||
/* Plus part credit having read full buffer */
|
||||
( ((bufsize - tmp) * write_score) /
|
||||
(read_score + write_score) )
|
||||
+ HALFCOUNT) / COUNTSIZE;
|
||||
stop_count();
|
||||
} else
|
||||
counted += count_per_buf;
|
||||
}
|
||||
}
|
||||
|
||||
/* stop clock */
|
||||
end = getFloatTime();
|
||||
copy_score = (long) ((double) counted / ((end - start) * count_per_k));
|
||||
printf("Copy done: %ld in %.4f, score %ld\n",
|
||||
counted, end - start, copy_score);
|
||||
|
||||
/*
|
||||
* Output the test results. Use the true time.
|
||||
*/
|
||||
fprintf(stderr, "COUNT|%ld|0|KBps\n", copy_score);
|
||||
fprintf(stderr, "TIME|%.1f\n", end - start);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
void stop_count(void)
|
||||
{
|
||||
extern int sigalarm;
|
||||
sigalarm = 1;
|
||||
}
|
||||
|
||||
void clean_up(void)
|
||||
{
|
||||
unlink(FNAME0);
|
||||
unlink(FNAME1);
|
||||
}
|
77
UnixBench/src/hanoi.c
Normal file
77
UnixBench/src/hanoi.c
Normal file
@ -0,0 +1,77 @@
|
||||
/*******************************************************************************
|
||||
* The BYTE UNIX Benchmarks - Release 3
|
||||
* Module: hanoi.c SID: 3.3 5/15/91 19:30:20
|
||||
*
|
||||
*******************************************************************************
|
||||
* Bug reports, patches, comments, suggestions should be sent to:
|
||||
*
|
||||
* Ben Smith, Rick Grehan or Tom Yager
|
||||
* ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
|
||||
*
|
||||
*******************************************************************************
|
||||
* Modification Log:
|
||||
* $Header: hanoi.c,v 3.5 87/08/06 08:11:14 kenj Exp $
|
||||
* August 28, 1990 - Modified timing routines (ty)
|
||||
* October 22, 1997 - code cleanup to remove ANSI C compiler warnings
|
||||
* Andy Kahn <kahn@zk3.dec.com>
|
||||
*
|
||||
******************************************************************************/
|
||||
char SCCSid[] = "@(#) @(#)hanoi.c:3.3 -- 5/15/91 19:30:20";
|
||||
|
||||
#define other(i,j) (6-(i+j))
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "timeit.c"
|
||||
|
||||
void mov(int n, int f, int t);
|
||||
|
||||
unsigned long iter = 0;
|
||||
int num[4];
|
||||
long cnt;
|
||||
|
||||
void report()
|
||||
{
|
||||
fprintf(stderr,"COUNT|%ld|1|lps\n", iter);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
int main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
int disk=10, /* default number of disks */
|
||||
duration;
|
||||
|
||||
if (argc < 2) {
|
||||
fprintf(stderr,"Usage: %s duration [disks]\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
duration = atoi(argv[1]);
|
||||
if(argc > 2) disk = atoi(argv[2]);
|
||||
num[1] = disk;
|
||||
|
||||
wake_me(duration, report);
|
||||
|
||||
while(1) {
|
||||
mov(disk,1,3);
|
||||
iter++;
|
||||
}
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void mov(int n, int f, int t)
|
||||
{
|
||||
int o;
|
||||
if(n == 1) {
|
||||
num[f]--;
|
||||
num[t]++;
|
||||
return;
|
||||
}
|
||||
o = other(f,t);
|
||||
mov(n-1,f,o);
|
||||
mov(1,f,t);
|
||||
mov(n-1,o,t);
|
||||
}
|
105
UnixBench/src/looper.c
Normal file
105
UnixBench/src/looper.c
Normal file
@ -0,0 +1,105 @@
|
||||
/*******************************************************************************
|
||||
* The BYTE UNIX Benchmarks - Release 1
|
||||
* Module: looper.c SID: 1.4 5/15/91 19:30:22
|
||||
*
|
||||
*******************************************************************************
|
||||
* Bug reports, patches, comments, suggestions should be sent to:
|
||||
*
|
||||
* Ben Smith or Tom Yager at BYTE Magazine
|
||||
* ben@bytepb.byte.com tyager@bytepb.byte.com
|
||||
*
|
||||
*******************************************************************************
|
||||
* Modification Log:
|
||||
*
|
||||
* February 25, 1991 -- created (Ben S.)
|
||||
* October 22, 1997 - code cleanup to remove ANSI C compiler warnings
|
||||
* Andy Kahn <kahn@zk3.dec.com>
|
||||
*
|
||||
******************************************************************************/
|
||||
char SCCSid[] = "@(#) @(#)looper.c:1.4 -- 5/15/91 19:30:22";
|
||||
/*
|
||||
* Shell Process creation
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/wait.h>
|
||||
#include "timeit.c"
|
||||
|
||||
unsigned long iter;
|
||||
char *cmd_argv[28];
|
||||
int cmd_argc;
|
||||
|
||||
void report(void)
|
||||
{
|
||||
fprintf(stderr,"COUNT|%lu|60|lpm\n", iter);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
int slave, count, duration;
|
||||
int status;
|
||||
|
||||
if (argc < 2)
|
||||
{
|
||||
fprintf(stderr,"Usage: %s duration command [args..]\n", argv[0]);
|
||||
fprintf(stderr," duration in seconds\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if((duration = atoi(argv[1])) < 1)
|
||||
{
|
||||
fprintf(stderr,"Usage: %s duration command [arg..]\n", argv[0]);
|
||||
fprintf(stderr," duration in seconds\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* get command */
|
||||
cmd_argc=argc-2;
|
||||
for( count=2;count < argc; ++count)
|
||||
cmd_argv[count-2]=argv[count];
|
||||
#ifdef DEBUG
|
||||
printf("<<%s>>",cmd_argv[0]);
|
||||
for(count=1;count < cmd_argc; ++count)
|
||||
printf(" <%s>", cmd_argv[count]);
|
||||
putchar('\n');
|
||||
exit(0);
|
||||
#endif
|
||||
|
||||
iter = 0;
|
||||
wake_me(duration, report);
|
||||
|
||||
while (1)
|
||||
{
|
||||
if ((slave = fork()) == 0)
|
||||
{ /* execute command */
|
||||
execvp(cmd_argv[0],cmd_argv);
|
||||
exit(99);
|
||||
}
|
||||
else if (slave < 0)
|
||||
{
|
||||
/* woops ... */
|
||||
fprintf(stderr,"Fork failed at iteration %lu\n", iter);
|
||||
perror("Reason");
|
||||
exit(2);
|
||||
}
|
||||
else
|
||||
/* master */
|
||||
wait(&status);
|
||||
if (status == 99 << 8)
|
||||
{
|
||||
fprintf(stderr, "Command \"%s\" didn't exec\n", cmd_argv[0]);
|
||||
exit(2);
|
||||
}
|
||||
else if (status != 0)
|
||||
{
|
||||
fprintf(stderr,"Bad wait status: 0x%x\n", status);
|
||||
exit(2);
|
||||
}
|
||||
iter++;
|
||||
}
|
||||
}
|
68
UnixBench/src/pipe.c
Normal file
68
UnixBench/src/pipe.c
Normal file
@ -0,0 +1,68 @@
|
||||
/*******************************************************************************
|
||||
* The BYTE UNIX Benchmarks - Release 3
|
||||
* Module: pipe.c SID: 3.3 5/15/91 19:30:20
|
||||
*
|
||||
*******************************************************************************
|
||||
* Bug reports, patches, comments, suggestions should be sent to:
|
||||
*
|
||||
* Ben Smith, Rick Grehan or Tom Yager
|
||||
* ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
|
||||
*
|
||||
*******************************************************************************
|
||||
* Modification Log:
|
||||
* $Header: pipe.c,v 3.5 87/06/22 14:32:36 kjmcdonell Beta $
|
||||
* August 29, 1990 - modified timing routines (ty)
|
||||
* October 22, 1997 - code cleanup to remove ANSI C compiler warnings
|
||||
* Andy Kahn <kahn@zk3.dec.com>
|
||||
*
|
||||
******************************************************************************/
|
||||
char SCCSid[] = "@(#) @(#)pipe.c:3.3 -- 5/15/91 19:30:20";
|
||||
/*
|
||||
* pipe -- test single process pipe throughput (no context switching)
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include "timeit.c"
|
||||
|
||||
unsigned long iter;
|
||||
|
||||
void report()
|
||||
{
|
||||
fprintf(stderr,"COUNT|%ld|1|lps\n", iter);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
char buf[512];
|
||||
int pvec[2], duration;
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr,"Usage: %s duration\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
duration = atoi(argv[1]);
|
||||
|
||||
pipe(pvec);
|
||||
|
||||
wake_me(duration, report);
|
||||
iter = 0;
|
||||
|
||||
while (1) {
|
||||
if (write(pvec[1], buf, sizeof(buf)) != sizeof(buf)) {
|
||||
if ((errno != EINTR) && (errno != 0))
|
||||
fprintf(stderr,"write failed, error %d\n", errno);
|
||||
}
|
||||
if (read(pvec[0], buf, sizeof(buf)) != sizeof(buf)) {
|
||||
if ((errno != EINTR) && (errno != 0))
|
||||
fprintf(stderr,"read failed, error %d\n", errno);
|
||||
}
|
||||
iter++;
|
||||
}
|
||||
}
|
80
UnixBench/src/spawn.c
Normal file
80
UnixBench/src/spawn.c
Normal file
@ -0,0 +1,80 @@
|
||||
/*******************************************************************************
|
||||
* The BYTE UNIX Benchmarks - Release 3
|
||||
* Module: spawn.c SID: 3.3 5/15/91 19:30:20
|
||||
*
|
||||
*******************************************************************************
|
||||
* Bug reports, patches, comments, suggestions should be sent to:
|
||||
*
|
||||
* Ben Smith, Rick Grehan or Tom Yagerat BYTE Magazine
|
||||
* ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
|
||||
*
|
||||
*******************************************************************************
|
||||
* Modification Log:
|
||||
* $Header: spawn.c,v 3.4 87/06/22 14:32:48 kjmcdonell Beta $
|
||||
* August 29, 1990 - Modified timing routines (ty)
|
||||
* October 22, 1997 - code cleanup to remove ANSI C compiler warnings
|
||||
* Andy Kahn <kahn@zk3.dec.com>
|
||||
*
|
||||
******************************************************************************/
|
||||
char SCCSid[] = "@(#) @(#)spawn.c:3.3 -- 5/15/91 19:30:20";
|
||||
/*
|
||||
* Process creation
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/wait.h>
|
||||
#include "timeit.c"
|
||||
|
||||
unsigned long iter;
|
||||
|
||||
void report()
|
||||
{
|
||||
fprintf(stderr,"COUNT|%lu|1|lps\n", iter);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
int slave, duration;
|
||||
int status;
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr,"Usage: %s duration \n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
duration = atoi(argv[1]);
|
||||
|
||||
iter = 0;
|
||||
wake_me(duration, report);
|
||||
|
||||
while (1) {
|
||||
if ((slave = fork()) == 0) {
|
||||
/* slave .. boring */
|
||||
#if debug
|
||||
printf("fork OK\n");
|
||||
#endif
|
||||
/* kill it right away */
|
||||
exit(0);
|
||||
} else if (slave < 0) {
|
||||
/* woops ... */
|
||||
fprintf(stderr,"Fork failed at iteration %lu\n", iter);
|
||||
perror("Reason");
|
||||
exit(2);
|
||||
} else
|
||||
/* master */
|
||||
wait(&status);
|
||||
if (status != 0) {
|
||||
fprintf(stderr,"Bad wait status: 0x%x\n", status);
|
||||
exit(2);
|
||||
}
|
||||
iter++;
|
||||
#if debug
|
||||
printf("Child %d done.\n", slave);
|
||||
#endif
|
||||
}
|
||||
}
|
109
UnixBench/src/syscall.c
Normal file
109
UnixBench/src/syscall.c
Normal file
@ -0,0 +1,109 @@
|
||||
/*******************************************************************************
|
||||
* The BYTE UNIX Benchmarks - Release 3
|
||||
* Module: syscall.c SID: 3.3 5/15/91 19:30:21
|
||||
*
|
||||
*******************************************************************************
|
||||
* Bug reports, patches, comments, suggestions should be sent to:
|
||||
*
|
||||
* Ben Smith, Rick Grehan or Tom Yager at BYTE Magazine
|
||||
* ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
|
||||
*
|
||||
*******************************************************************************
|
||||
* Modification Log:
|
||||
* $Header: syscall.c,v 3.4 87/06/22 14:32:54 kjmcdonell Beta $
|
||||
* August 29, 1990 - Modified timing routines
|
||||
* October 22, 1997 - code cleanup to remove ANSI C compiler warnings
|
||||
* Andy Kahn <kahn@zk3.dec.com>
|
||||
*
|
||||
******************************************************************************/
|
||||
/*
|
||||
* syscall -- sit in a loop calling the system
|
||||
*
|
||||
*/
|
||||
char SCCSid[] = "@(#) @(#)syscall.c:3.3 -- 5/15/91 19:30:21";
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include "timeit.c"
|
||||
|
||||
unsigned long iter;
|
||||
|
||||
void report()
|
||||
{
|
||||
fprintf(stderr,"COUNT|%ld|1|lps\n", iter);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
char *test;
|
||||
int duration;
|
||||
|
||||
if (argc < 2) {
|
||||
fprintf(stderr,"Usage: %s duration [ test ]\n", argv[0]);
|
||||
fprintf(stderr,"test is one of:\n");
|
||||
fprintf(stderr," \"mix\" (default), \"close\", \"getpid\", \"exec\"\n");
|
||||
exit(1);
|
||||
}
|
||||
if (argc > 2)
|
||||
test = argv[2];
|
||||
else
|
||||
test = "mix";
|
||||
|
||||
duration = atoi(argv[1]);
|
||||
|
||||
iter = 0;
|
||||
wake_me(duration, report);
|
||||
|
||||
switch (test[0]) {
|
||||
case 'm':
|
||||
while (1) {
|
||||
close(dup(0));
|
||||
getpid();
|
||||
getuid();
|
||||
umask(022);
|
||||
iter++;
|
||||
}
|
||||
/* NOTREACHED */
|
||||
case 'c':
|
||||
while (1) {
|
||||
close(dup(0));
|
||||
iter++;
|
||||
}
|
||||
/* NOTREACHED */
|
||||
case 'g':
|
||||
while (1) {
|
||||
getpid();
|
||||
iter++;
|
||||
}
|
||||
/* NOTREACHED */
|
||||
case 'e':
|
||||
while (1) {
|
||||
pid_t pid = fork();
|
||||
if (pid < 0) {
|
||||
fprintf(stderr,"%s: fork failed\n", argv[0]);
|
||||
exit(1);
|
||||
} else if (pid == 0) {
|
||||
execl("/bin/true", (char *) 0);
|
||||
fprintf(stderr,"%s: exec /bin/true failed\n", argv[0]);
|
||||
exit(1);
|
||||
} else {
|
||||
if (waitpid(pid, NULL, 0) < 0) {
|
||||
fprintf(stderr,"%s: waitpid failed\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
iter++;
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
exit(9);
|
||||
}
|
||||
|
573
UnixBench/src/time-polling.c
Normal file
573
UnixBench/src/time-polling.c
Normal file
@ -0,0 +1,573 @@
|
||||
/* Programme to test how long it takes to select(2), poll(2) and poll2(2) a
|
||||
large number of file descriptors.
|
||||
|
||||
Copyright 1997 Richard Gooch rgooch@atnf.csiro.au
|
||||
Distributed under the GNU General Public License.
|
||||
|
||||
To compile this programme, use gcc -O2 -o time-polling time-polling.c
|
||||
|
||||
Extra compile flags:
|
||||
|
||||
Add -DHAS_SELECT if your operating system has the select(2) system call
|
||||
Add -DHAS_POLL if your operating system has the poll(2) system call
|
||||
Add -DHAS_POLL2 if your operating system has the poll2(2) system call
|
||||
|
||||
Usage: time-polling [num_iter] [num_to_test] [num_active] [-v]
|
||||
|
||||
NOTE: on many systems the default limit on file descriptors is less than
|
||||
1024. You should try to increase this limit to 1024 before doing the test.
|
||||
Something like "limit descriptors 1024" or "limit openfiles 1024" should do
|
||||
the trick. On some systems (like IRIX), doing the test on a smaller number
|
||||
gives a *much* smaller time per descriptor, which shows that time taken
|
||||
does not scale linearly with number of descriptors, which is non-optimal.
|
||||
In the tests I've done, I try to use 1024 descriptors.
|
||||
The benchmark results are available at:
|
||||
http://www.atnf.csiro.au/~rgooch/benchmarks.html
|
||||
If you want to contribute results, please email them to me. Please specify
|
||||
if you want to be acknowledged.
|
||||
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Richard Gooch may be reached by email at rgooch@atnf.csiro.au
|
||||
The postal address is:
|
||||
Richard Gooch, c/o ATNF, P. O. Box 76, Epping, N.S.W., 2121, Australia.
|
||||
|
||||
*/
|
||||
|
||||
#ifdef UNIXBENCH
|
||||
#define OUT stdout
|
||||
#else
|
||||
#define OUT stderr
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#ifdef HAS_POLL
|
||||
# include <sys/poll.h>
|
||||
#endif
|
||||
#ifdef HAS_POLL2
|
||||
# include <linux/poll2.h>
|
||||
#endif
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#ifdef UNIXBENCH
|
||||
#define MAX_ITERATIONS 1000
|
||||
#else
|
||||
#define MAX_ITERATIONS 30
|
||||
#endif
|
||||
#define MAX_FDS 40960
|
||||
#define CONST const
|
||||
#define ERRSTRING strerror (errno)
|
||||
|
||||
typedef int flag;
|
||||
|
||||
|
||||
/*
|
||||
static inline int find_first_set_bit (CONST void *array, int size)
|
||||
*/
|
||||
static int find_first_set_bit (CONST void *array, int size)
|
||||
/* [SUMMARY] Find the first bit set in a bitfield.
|
||||
<array> A pointer to the bitfield. This must be aligned on a long boundary.
|
||||
<size> The number of bits in the bitfield.
|
||||
[RETURNS] The index of the first set bit. If no bits are set, <<size>> + 1
|
||||
is returned.
|
||||
*/
|
||||
{
|
||||
int index;
|
||||
unsigned long word;
|
||||
unsigned int ul_size = 8 * sizeof (unsigned long);
|
||||
CONST unsigned long *ul_array = array;
|
||||
|
||||
/* Find first word with any bit set */
|
||||
for (index = 0; (*ul_array == 0) && (index < size);
|
||||
index += ul_size, ++ul_array);
|
||||
/* Find first bit set in word */
|
||||
for (word = *ul_array; !(word & 1) && (index < size);
|
||||
++index, word = word >> 1);
|
||||
return (index);
|
||||
} /* End Function find_first_set_bit */
|
||||
|
||||
/*
|
||||
static inline int find_next_set_bit (CONST void *array, int size, int offset)
|
||||
*/
|
||||
static int find_next_set_bit (CONST void *array, int size, int offset)
|
||||
/* [SUMMARY] Find the next bit set in a bitfield.
|
||||
<array> A pointer to the bitfield. This must be aligned on a long boundary.
|
||||
<size> The number of bits in the bitfield.
|
||||
<offset> The offset of the current bit in the bitfield. The current bit is
|
||||
ignored.
|
||||
[RETURNS] The index of the next set bit. If no more bits are set,
|
||||
<<size>> + 1 is returned.
|
||||
*/
|
||||
{
|
||||
int index, tmp;
|
||||
unsigned long word;
|
||||
unsigned int ul_size = 8 * sizeof (unsigned long);
|
||||
CONST unsigned long *ul_array = array;
|
||||
|
||||
if (++offset >= size) return (offset);
|
||||
index = offset;
|
||||
/* Jump to the long word containing the next bit */
|
||||
tmp = offset / ul_size;
|
||||
ul_array += tmp;
|
||||
offset -= tmp * ul_size;
|
||||
if ( (offset == 0) || (*ul_array == 0) )
|
||||
return (find_first_set_bit (ul_array, size - index) + index);
|
||||
/* There is a bit set somewhere in this word */
|
||||
if ( ( (word = *ul_array) != 0 ) && ( (word = word >> offset) != 0 ) )
|
||||
{
|
||||
/* There is a bit set somewhere in this word at or after the offset
|
||||
position */
|
||||
for (; (word & 1) == 0; word = word >> 1, ++index);
|
||||
return (index);
|
||||
}
|
||||
/* Have to go to subsequent word(s) */
|
||||
index += ul_size - offset;
|
||||
return (find_first_set_bit (++ul_array, size - index) + index);
|
||||
} /* End Function find_next_set_bit */
|
||||
|
||||
|
||||
struct callback_struct
|
||||
{
|
||||
void (*input_func) (void *info);
|
||||
void (*output_func) (void *info);
|
||||
void (*exception_func) (void *info);
|
||||
void *info;
|
||||
};
|
||||
|
||||
static int total_bits = 0;
|
||||
struct callback_struct callbacks[MAX_FDS];
|
||||
|
||||
|
||||
static void test_func (void *info)
|
||||
{
|
||||
++total_bits;
|
||||
}
|
||||
|
||||
#ifdef HAS_SELECT
|
||||
static void time_select (fd_set *input_fds, fd_set *output_fds,
|
||||
fd_set *exception_fds, int max_fd, int num_iter,
|
||||
long *times)
|
||||
/* [SUMMARY] Time how long it takes to select(2) file descriptors.
|
||||
<input_fds> The input masks.
|
||||
<output_fds> The output masks.
|
||||
<exception_fds> The exception masks.
|
||||
<max_fd> The highest file descriptor in the fd_sets.
|
||||
<num_iter> The number of iterations.
|
||||
<times> The time taken (in microseconds) for each iteration.
|
||||
[RETURNS] Nothing.
|
||||
*/
|
||||
{
|
||||
int fd, count, nready;
|
||||
fd_set i_fds, o_fds, e_fds;
|
||||
struct timeval time1, time2, tv;
|
||||
|
||||
/* Warm the cache a bit */
|
||||
memcpy (&i_fds, input_fds, sizeof i_fds);
|
||||
memcpy (&o_fds, output_fds, sizeof i_fds);
|
||||
memcpy (&e_fds, exception_fds, sizeof i_fds);
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
select (max_fd + 1, &i_fds, &o_fds, &e_fds, &tv);
|
||||
for (count = 0; count < num_iter; ++count)
|
||||
{
|
||||
total_bits = 0;
|
||||
gettimeofday (&time1, NULL);
|
||||
memcpy (&i_fds, input_fds, sizeof i_fds);
|
||||
memcpy (&o_fds, output_fds, sizeof i_fds);
|
||||
memcpy (&e_fds, exception_fds, sizeof i_fds);
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
nready = select (max_fd + 1, &i_fds, &o_fds, &e_fds, &tv);
|
||||
if (nready == -1)
|
||||
{
|
||||
fprintf (stderr, "Error selecting\t%s\n", ERRSTRING);
|
||||
exit (2);
|
||||
}
|
||||
if (nready < 1)
|
||||
{
|
||||
fprintf (stderr, "Error: nready: %d\n", nready);
|
||||
exit (1);
|
||||
}
|
||||
/* Scan the output */
|
||||
for (fd = find_first_set_bit (&e_fds, sizeof e_fds * 8); fd <= max_fd;
|
||||
fd = find_next_set_bit (&e_fds, sizeof e_fds * 8, fd) )
|
||||
{
|
||||
(*callbacks[fd].exception_func) (callbacks[fd].info);
|
||||
}
|
||||
for (fd = find_first_set_bit (&i_fds, sizeof i_fds * 8); fd <= max_fd;
|
||||
fd = find_next_set_bit (&i_fds, sizeof i_fds * 8, fd) )
|
||||
{
|
||||
(*callbacks[fd].input_func) (callbacks[fd].info);
|
||||
}
|
||||
for (fd = find_first_set_bit (&o_fds, sizeof o_fds * 8); fd <= max_fd;
|
||||
fd = find_next_set_bit (&o_fds, sizeof o_fds * 8, fd) )
|
||||
{
|
||||
(*callbacks[fd].output_func) (callbacks[fd].info);
|
||||
}
|
||||
gettimeofday (&time2, NULL);
|
||||
times[count] = (time2.tv_sec - time1.tv_sec) * 1000000;
|
||||
times[count] += time2.tv_usec - time1.tv_usec;
|
||||
}
|
||||
} /* End Function time_select */
|
||||
#endif /* HAS_SELECT */
|
||||
|
||||
#ifdef HAS_POLL
|
||||
static void time_poll (struct pollfd *pollfd_array, int start_index,
|
||||
int num_to_test, int num_iter, long *times)
|
||||
/* [SUMMARY] Time how long it takes to poll(2) file descriptors.
|
||||
<pollfd_array> The array of pollfd structures.
|
||||
<start_index> The start index in the array of pollfd structures.
|
||||
<num_to_test> The number of file descriptors to test.
|
||||
<num_iter> The number of iterations.
|
||||
<times> The time taken (in microseconds) for each iteration.
|
||||
[RETURNS] Nothing.
|
||||
*/
|
||||
{
|
||||
short revents;
|
||||
int fd, count, nready;
|
||||
struct timeval time1, time2;
|
||||
struct pollfd *pollfd_ptr, *stop_pollfd;
|
||||
|
||||
/* Warm the cache a bit */
|
||||
poll (pollfd_array + start_index, num_to_test, 0);
|
||||
for (count = 0; count < num_iter; ++count)
|
||||
{
|
||||
total_bits = 0;
|
||||
gettimeofday (&time1, NULL);
|
||||
nready = poll (pollfd_array + start_index, num_to_test, 0);
|
||||
if (nready == -1)
|
||||
{
|
||||
fprintf (stderr, "Error polling\t%s\n", ERRSTRING);
|
||||
exit (2);
|
||||
}
|
||||
if (nready < 1)
|
||||
{
|
||||
fprintf (stderr, "Error: nready: %d\n", nready);
|
||||
exit (1);
|
||||
}
|
||||
stop_pollfd = pollfd_array + start_index + num_to_test;
|
||||
for (pollfd_ptr = pollfd_array + start_index; TRUE; ++pollfd_ptr)
|
||||
{
|
||||
if (pollfd_ptr->revents == 0) continue;
|
||||
/* Have an active descriptor */
|
||||
revents = pollfd_ptr->revents;
|
||||
fd = pollfd_ptr->fd;
|
||||
if (revents & POLLPRI)
|
||||
(*callbacks[fd].exception_func) (callbacks[fd].info);
|
||||
if (revents & POLLIN)
|
||||
(*callbacks[fd].input_func) (callbacks[fd].info);
|
||||
if (revents & POLLOUT)
|
||||
(*callbacks[fd].output_func) (callbacks[fd].info);
|
||||
if (--nready == 0) break;
|
||||
}
|
||||
gettimeofday (&time2, NULL);
|
||||
times[count] = (time2.tv_sec - time1.tv_sec) * 1000000;
|
||||
times[count] += time2.tv_usec - time1.tv_usec;
|
||||
}
|
||||
} /* End Function time_poll */
|
||||
#endif /* HAS_POLL */
|
||||
|
||||
#ifdef HAS_POLL2
|
||||
static void time_poll2 (struct poll2ifd *poll2ifd_array, int start_index,
|
||||
int num_to_test, int num_iter, long *times)
|
||||
/* [SUMMARY] Time how long it takes to poll2(2) file descriptors.
|
||||
<poll2ifd_array> The array of poll2ifd structures.
|
||||
<start_index> The start index in the array of pollfd structures.
|
||||
<num_to_test> The number of file descriptors to test.
|
||||
<num_iter> The number of iterations.
|
||||
<times> The time taken (in microseconds) for each iteration.
|
||||
[RETURNS] Nothing.
|
||||
*/
|
||||
{
|
||||
short revents;
|
||||
int fd, count, nready, i;
|
||||
struct timeval time1, time2;
|
||||
struct poll2ofd poll2ofd_array[MAX_FDS];
|
||||
|
||||
/* Warm the cache a bit */
|
||||
poll2 (poll2ifd_array + start_index, poll2ofd_array, num_to_test, 0);
|
||||
for (count = 0; count < num_iter; ++count)
|
||||
{
|
||||
total_bits = 0;
|
||||
gettimeofday (&time1, NULL);
|
||||
nready = poll2 (poll2ifd_array + start_index, poll2ofd_array,
|
||||
num_to_test, 0);
|
||||
if (nready == -1)
|
||||
{
|
||||
times[count] = -1;
|
||||
if (errno == ENOSYS) return; /* Must do this first */
|
||||
fprintf (stderr, "Error calling poll2(2)\t%s\n", ERRSTRING);
|
||||
exit (2);
|
||||
}
|
||||
if (nready < 1)
|
||||
{
|
||||
fprintf (stderr, "Error: nready: %d\n", nready);
|
||||
exit (1);
|
||||
}
|
||||
for (i = 0; i < nready; ++i)
|
||||
{
|
||||
revents = poll2ofd_array[i].revents;
|
||||
fd = poll2ofd_array[i].fd;
|
||||
if (revents & POLLPRI)
|
||||
(*callbacks[fd].exception_func) (callbacks[fd].info);
|
||||
if (revents & POLLIN)
|
||||
(*callbacks[fd].input_func) (callbacks[fd].info);
|
||||
if (revents & POLLOUT)
|
||||
(*callbacks[fd].output_func) (callbacks[fd].info);
|
||||
}
|
||||
gettimeofday (&time2, NULL);
|
||||
times[count] = (time2.tv_sec - time1.tv_sec) * 1000000;
|
||||
times[count] += time2.tv_usec - time1.tv_usec;
|
||||
}
|
||||
} /* End Function time_poll2 */
|
||||
#endif /* HAS_POLL2 */
|
||||
|
||||
|
||||
int main (argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
flag failed = FALSE;
|
||||
flag verbose = FALSE;
|
||||
int first_fd = -1;
|
||||
int fd, max_fd, count, total_fds;
|
||||
int num_to_test, num_active;
|
||||
#ifdef UNIXBENCH
|
||||
int max_iter = 1000;
|
||||
#else
|
||||
int max_iter = 10;
|
||||
#endif
|
||||
#ifdef HAS_SELECT
|
||||
long select_total = 0;
|
||||
fd_set input_fds, output_fds, exception_fds;
|
||||
long select_times[MAX_ITERATIONS];
|
||||
#endif
|
||||
#ifdef HAS_POLL
|
||||
int start_index;
|
||||
long poll_total = 0;
|
||||
struct pollfd pollfd_array[MAX_FDS];
|
||||
long poll_times[MAX_ITERATIONS];
|
||||
#endif
|
||||
#ifdef HAS_POLL2
|
||||
long poll2_total = 0;
|
||||
struct poll2ifd poll2ifd_array[MAX_FDS];
|
||||
struct poll2ofd poll2ofd_array[MAX_FDS];
|
||||
long poll2_times[MAX_ITERATIONS];
|
||||
#endif
|
||||
#if 0
|
||||
extern char *sys_errlist[];
|
||||
#endif
|
||||
|
||||
#ifdef HAS_SELECT
|
||||
FD_ZERO (&input_fds);
|
||||
FD_ZERO (&output_fds);
|
||||
FD_ZERO (&exception_fds);
|
||||
#endif
|
||||
#ifdef HAS_POLL
|
||||
memset (pollfd_array, 0, sizeof pollfd_array);
|
||||
#endif
|
||||
/* Allocate file descriptors */
|
||||
total_fds = 0;
|
||||
max_fd = 0;
|
||||
while (!failed)
|
||||
{
|
||||
if ( ( fd = dup (1) ) == -1 )
|
||||
{
|
||||
if (errno != EMFILE)
|
||||
{
|
||||
fprintf (stderr, "Error dup()ing\t%s\n", ERRSTRING);
|
||||
exit (1);
|
||||
}
|
||||
failed = TRUE;
|
||||
continue;
|
||||
}
|
||||
if (fd >= MAX_FDS)
|
||||
{
|
||||
fprintf (stderr, "File descriptor: %d larger than max: %d\n",
|
||||
fd, MAX_FDS - 1);
|
||||
exit (1);
|
||||
}
|
||||
callbacks[fd].input_func = test_func;
|
||||
callbacks[fd].output_func = test_func;
|
||||
callbacks[fd].exception_func = test_func;
|
||||
callbacks[fd].info = NULL;
|
||||
if (fd > max_fd) max_fd = fd;
|
||||
if (first_fd < 0) first_fd = fd;
|
||||
#ifdef HAS_POLL
|
||||
pollfd_array[fd].fd = fd;
|
||||
pollfd_array[fd].events = 0;
|
||||
#endif
|
||||
#ifdef HAS_POLL2
|
||||
poll2ifd_array[fd].fd = fd;
|
||||
poll2ifd_array[fd].events = 0;
|
||||
#endif
|
||||
}
|
||||
total_fds = max_fd + 1;
|
||||
/* Process the command-line arguments */
|
||||
if (argc > 5)
|
||||
{
|
||||
fputs ("Usage:\ttime-polling [num_iter] [num_to_test] [num_active] [-v]\n",
|
||||
stderr);
|
||||
exit (1);
|
||||
}
|
||||
if (argc > 1) max_iter = atoi (argv[1]);
|
||||
if (max_iter > MAX_ITERATIONS)
|
||||
{
|
||||
fprintf (stderr, "num_iter too large\n");
|
||||
exit (1);
|
||||
}
|
||||
if (argc > 2) num_to_test = atoi (argv[2]);
|
||||
else num_to_test = total_fds - first_fd;
|
||||
if (argc > 3) num_active = atoi (argv[3]);
|
||||
else num_active = 1;
|
||||
if (argc > 4)
|
||||
{
|
||||
if (strcmp (argv[4], "-v") != 0)
|
||||
{
|
||||
fputs ("Usage:\ttime-polling [num_iter] [num_to_test] [num_active] [-v]\n",
|
||||
stderr);
|
||||
exit (1);
|
||||
}
|
||||
verbose = TRUE;
|
||||
}
|
||||
|
||||
/* Sanity tests */
|
||||
if (num_to_test > total_fds - first_fd) num_to_test = total_fds - first_fd;
|
||||
if (num_active > total_fds - first_fd) num_active = total_fds - first_fd;
|
||||
/* Set activity monitoring flags */
|
||||
for (fd = total_fds - num_to_test; fd < total_fds; ++fd)
|
||||
{
|
||||
#ifdef HAS_SELECT
|
||||
FD_SET (fd, &exception_fds);
|
||||
FD_SET (fd, &input_fds);
|
||||
#endif
|
||||
#ifdef HAS_POLL
|
||||
pollfd_array[fd].events = POLLPRI | POLLIN;
|
||||
#endif
|
||||
#ifdef HAS_POLL2
|
||||
poll2ifd_array[fd].events = POLLPRI | POLLIN;
|
||||
#endif
|
||||
}
|
||||
for (fd = total_fds - num_active; fd < total_fds; ++fd)
|
||||
{
|
||||
#ifdef HAS_SELECT
|
||||
FD_SET (fd, &output_fds);
|
||||
#endif
|
||||
#ifdef HAS_POLL
|
||||
pollfd_array[fd].events |= POLLOUT;
|
||||
#endif
|
||||
#ifdef HAS_POLL2
|
||||
poll2ifd_array[fd].events |= POLLOUT;
|
||||
#endif
|
||||
}
|
||||
fprintf (OUT, "Num fds: %d, polling descriptors %d-%d\n",
|
||||
total_fds, total_fds - num_to_test, max_fd);
|
||||
/* First do all the tests, then print the results */
|
||||
#ifdef HAS_SELECT
|
||||
time_select (&input_fds, &output_fds, &exception_fds, max_fd, max_iter,
|
||||
select_times);
|
||||
#endif
|
||||
#ifdef HAS_POLL
|
||||
start_index = total_fds - num_to_test;
|
||||
time_poll (pollfd_array, start_index, num_to_test, max_iter, poll_times);
|
||||
#endif
|
||||
#ifdef HAS_POLL2
|
||||
start_index = total_fds - num_to_test;
|
||||
time_poll2 (poll2ifd_array, start_index, num_to_test, max_iter,
|
||||
poll2_times);
|
||||
#endif
|
||||
/* Now print out all the times */
|
||||
fputs ("All times in microseconds\n", OUT);
|
||||
fputs ("ITERATION\t", OUT);
|
||||
#ifdef HAS_SELECT
|
||||
fprintf (OUT, "%-12s", "select(2)");
|
||||
#endif
|
||||
#ifdef HAS_POLL
|
||||
fprintf (OUT, "%-12s", "poll(2)");
|
||||
#endif
|
||||
#ifdef HAS_POLL2
|
||||
if (poll2_times[0] >= 0) fprintf (OUT, "%-12s", "poll2(2)");
|
||||
#endif
|
||||
for (count = 0; count < max_iter; ++count)
|
||||
{
|
||||
if (verbose) fprintf (OUT, "\n%d\t\t", count);
|
||||
#ifdef HAS_SELECT
|
||||
if (verbose) fprintf (OUT, "%-12ld", select_times[count]);
|
||||
select_total += select_times[count];
|
||||
#endif
|
||||
#ifdef HAS_POLL
|
||||
if (verbose) fprintf (OUT, "%-12ld", poll_times[count]);
|
||||
poll_total += poll_times[count];
|
||||
#endif
|
||||
#ifdef HAS_POLL2
|
||||
if ( verbose && (poll2_times[0] >= 0) )
|
||||
fprintf (OUT, "%-12ld", poll2_times[count]);
|
||||
poll2_total += poll2_times[count];
|
||||
#endif
|
||||
}
|
||||
fputs ("\n\naverage\t\t", OUT);
|
||||
#ifdef HAS_SELECT
|
||||
fprintf (OUT, "%-12ld", select_total / max_iter);
|
||||
#endif
|
||||
#ifdef HAS_POLL
|
||||
fprintf (OUT, "%-12ld", poll_total / max_iter);
|
||||
#endif
|
||||
#ifdef HAS_POLL2
|
||||
if (poll2_times[0] >= 0)
|
||||
fprintf (OUT, "%-12ld", poll2_total / max_iter);
|
||||
#endif
|
||||
putc ('\n', OUT);
|
||||
fputs ("Per fd\t\t", OUT);
|
||||
#ifdef HAS_SELECT
|
||||
fprintf (OUT, "%-12.2f",
|
||||
(float) select_total / (float) max_iter / (float) num_to_test);
|
||||
#ifdef UNIXBENCH
|
||||
fprintf (stderr, "lps\t%.2f\t%.1f\n",
|
||||
1000000 * (float) max_iter * (float) num_to_test
|
||||
/ (float) select_total, (float)select_total / 1000000);
|
||||
#endif
|
||||
#endif
|
||||
#ifdef HAS_POLL
|
||||
fprintf (OUT, "%-12.2f",
|
||||
(float) poll_total / (float) max_iter / (float) num_to_test);
|
||||
#ifdef UNIXBENCH
|
||||
fprintf (stderr, "lps\t%.2f\t%.1f\n",
|
||||
1000000 * (float) max_iter * (float) num_to_test
|
||||
/ (float) poll_total, (float)poll_total / 1000000);
|
||||
#endif
|
||||
#endif
|
||||
#ifdef HAS_POLL2
|
||||
if (poll2_times[0] >= 0) {
|
||||
fprintf (OUT, "%-12.2f",
|
||||
(float) poll2_total / (float) max_iter / (float) num_to_test);
|
||||
#ifdef UNIXBENCH
|
||||
fprintf (stderr, "lps\t%.2f\t%.1f\n",
|
||||
1000000 * (float) max_iter * (float) num_to_test
|
||||
/ (float) poll2_total, (float)poll2_total / 1000000);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
fputs ("<- the most important value\n", OUT);
|
||||
|
||||
exit(0);
|
||||
} /* End Function main */
|
41
UnixBench/src/timeit.c
Normal file
41
UnixBench/src/timeit.c
Normal file
@ -0,0 +1,41 @@
|
||||
/*******************************************************************************
|
||||
*
|
||||
* The BYTE UNIX Benchmarks - Release 3
|
||||
* Module: timeit.c SID: 3.3 5/15/91 19:30:21
|
||||
*******************************************************************************
|
||||
* Bug reports, patches, comments, suggestions should be sent to:
|
||||
*
|
||||
* Ben Smith, Rick Grehan or Tom Yager
|
||||
* ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
|
||||
*
|
||||
*******************************************************************************
|
||||
* Modification Log:
|
||||
* May 12, 1989 - modified empty loops to avoid nullifying by optimizing
|
||||
* compilers
|
||||
* August 28, 1990 - changed timing relationship--now returns total number
|
||||
* of iterations (ty)
|
||||
* October 22, 1997 - code cleanup to remove ANSI C compiler warnings
|
||||
* Andy Kahn <kahn@zk3.dec.com>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/* this module is #included in other modules--no separate SCCS ID */
|
||||
|
||||
/*
|
||||
* Timing routine
|
||||
*
|
||||
*/
|
||||
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
|
||||
void wake_me(seconds, func)
|
||||
int seconds;
|
||||
void (*func)();
|
||||
{
|
||||
/* set up the signal handler */
|
||||
signal(SIGALRM, func);
|
||||
/* get the clock running */
|
||||
alarm(seconds);
|
||||
}
|
||||
|
650
UnixBench/src/ubgears.c
Normal file
650
UnixBench/src/ubgears.c
Normal file
@ -0,0 +1,650 @@
|
||||
/*
|
||||
* Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
/* $XFree86: xc/programs/glxgears/glxgears.c,v 1.3tsi Exp $ */
|
||||
|
||||
/*
|
||||
* This is a port of the infamous "gears" demo to straight GLX (i.e. no GLUT)
|
||||
* Port by Brian Paul 23 March 2001
|
||||
*
|
||||
* Exact timing added by Behdad Esfahbod to achieve a fixed speed regardless
|
||||
* of frame rate. November 2003
|
||||
*
|
||||
* Printer support added by Roland Mainz <roland.mainz@nrubsig.org>. April 2004
|
||||
*
|
||||
* This version modified by Ian Smith, 30 Sept 2007, to make ubgears.
|
||||
* ubgears is cusoimised for use in the UnixBench benchmarking suite.
|
||||
* Some redundant stuff is gone, and the -time option is added.
|
||||
* Mainly it's forked so we don't use the host's version, which could change
|
||||
* from platform to platform.
|
||||
*
|
||||
* Command line options:
|
||||
* -display Set X11 display for output.
|
||||
* -info Print additional GLX information.
|
||||
* -time <t> Run for <t> seconds and produce a performance report.
|
||||
* -h Print this help page.
|
||||
* -v Verbose output.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/keysym.h>
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glx.h>
|
||||
#include <sys/time.h>
|
||||
#include <sched.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265
|
||||
#endif /* !M_PI */
|
||||
|
||||
/* Turn a NULL pointer string into an empty string */
|
||||
#define NULLSTR(x) (((x)!=NULL)?(x):(""))
|
||||
#define Log(x) { if(verbose) printf x; }
|
||||
#define Msg(x) { printf x; }
|
||||
|
||||
/* Globla vars */
|
||||
/* program name (from argv[0]) */
|
||||
static const char *ProgramName;
|
||||
|
||||
/* verbose output what the program is doing */
|
||||
static Bool verbose = False;
|
||||
|
||||
/* time in microseconds to run for; -1 means forever. */
|
||||
static int runTime = -1;
|
||||
|
||||
/* Time at which start_time(void) was called. */
|
||||
static struct timeval clockStart;
|
||||
|
||||
/* XXX this probably isn't very portable */
|
||||
|
||||
/* return current time (in seconds) */
|
||||
static void
|
||||
start_time(void)
|
||||
{
|
||||
(void) gettimeofday(&clockStart, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* return time (in microseconds) since start_time(void) was called.
|
||||
*
|
||||
* The older version of this function randomly returned negative results.
|
||||
* This version won't, up to 2000 seconds and some.
|
||||
*/
|
||||
static long
|
||||
current_time(void)
|
||||
{
|
||||
struct timeval tv;
|
||||
long secs, micros;
|
||||
|
||||
(void) gettimeofday(&tv, 0);
|
||||
|
||||
secs = tv.tv_sec - clockStart.tv_sec;
|
||||
micros = tv.tv_usec - clockStart.tv_usec;
|
||||
if (micros < 0) {
|
||||
--secs;
|
||||
micros += 1000000;
|
||||
}
|
||||
return secs * 1000000 + micros;
|
||||
}
|
||||
|
||||
static
|
||||
void usage(void)
|
||||
{
|
||||
fprintf (stderr, "usage: %s [options]\n", ProgramName);
|
||||
fprintf (stderr, "-display\tSet X11 display for output.\n");
|
||||
fprintf (stderr, "-info\t\tPrint additional GLX information.\n");
|
||||
fprintf (stderr, "-time t\t\tRun for t seconds and report performance.\n");
|
||||
fprintf (stderr, "-h\t\tPrint this help page.\n");
|
||||
fprintf (stderr, "-v\t\tVerbose output.\n");
|
||||
fprintf (stderr, "\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
||||
static GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0;
|
||||
static GLint gear1, gear2, gear3;
|
||||
static GLfloat angle = 0.0;
|
||||
static GLint speed = 60;
|
||||
static GLboolean printInfo = GL_FALSE;
|
||||
|
||||
/*
|
||||
*
|
||||
* Draw a gear wheel. You'll probably want to call this function when
|
||||
* building a display list since we do a lot of trig here.
|
||||
*
|
||||
* Input: inner_radius - radius of hole at center
|
||||
* outer_radius - radius at center of teeth
|
||||
* width - width of gear
|
||||
* teeth - number of teeth
|
||||
* tooth_depth - depth of tooth
|
||||
*/
|
||||
static void
|
||||
gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width,
|
||||
GLint teeth, GLfloat tooth_depth)
|
||||
{
|
||||
GLint i;
|
||||
GLfloat r0, r1, r2, maxr2, minr2;
|
||||
GLfloat angle, da;
|
||||
GLfloat u, v, len;
|
||||
|
||||
r0 = inner_radius;
|
||||
r1 = outer_radius - tooth_depth / 2.0;
|
||||
maxr2 = r2 = outer_radius + tooth_depth / 2.0;
|
||||
minr2 = r2;
|
||||
|
||||
da = 2.0 * M_PI / teeth / 4.0;
|
||||
|
||||
glShadeModel(GL_FLAT);
|
||||
|
||||
glNormal3f(0.0, 0.0, 1.0);
|
||||
|
||||
/* draw front face */
|
||||
glBegin(GL_QUAD_STRIP);
|
||||
for (i = 0; i <= teeth; i++) {
|
||||
angle = i * 2.0 * M_PI / teeth;
|
||||
glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
|
||||
glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
|
||||
if (i < teeth) {
|
||||
glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
|
||||
glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
|
||||
width * 0.5);
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
|
||||
/* draw front sides of teeth */
|
||||
glBegin(GL_QUADS);
|
||||
for (i = 0; i < teeth; i++) {
|
||||
angle = i * 2.0 * M_PI / teeth;
|
||||
|
||||
glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
|
||||
glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
|
||||
glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
|
||||
width * 0.5);
|
||||
glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
|
||||
width * 0.5);
|
||||
r2 = minr2;
|
||||
}
|
||||
r2 = maxr2;
|
||||
glEnd();
|
||||
|
||||
glNormal3f(0.0, 0.0, -1.0);
|
||||
|
||||
/* draw back face */
|
||||
glBegin(GL_QUAD_STRIP);
|
||||
for (i = 0; i <= teeth; i++) {
|
||||
angle = i * 2.0 * M_PI / teeth;
|
||||
glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
|
||||
glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
|
||||
if (i < teeth) {
|
||||
glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
|
||||
-width * 0.5);
|
||||
glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
|
||||
/* draw back sides of teeth */
|
||||
glBegin(GL_QUADS);
|
||||
da = 2.0 * M_PI / teeth / 4.0;
|
||||
for (i = 0; i < teeth; i++) {
|
||||
angle = i * 2.0 * M_PI / teeth;
|
||||
|
||||
glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
|
||||
-width * 0.5);
|
||||
glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
|
||||
-width * 0.5);
|
||||
glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
|
||||
glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
|
||||
r2 = minr2;
|
||||
}
|
||||
r2 = maxr2;
|
||||
glEnd();
|
||||
|
||||
/* draw outward faces of teeth */
|
||||
glBegin(GL_QUAD_STRIP);
|
||||
for (i = 0; i < teeth; i++) {
|
||||
angle = i * 2.0 * M_PI / teeth;
|
||||
|
||||
glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
|
||||
glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
|
||||
u = r2 * cos(angle + da) - r1 * cos(angle);
|
||||
v = r2 * sin(angle + da) - r1 * sin(angle);
|
||||
len = sqrt(u * u + v * v);
|
||||
u /= len;
|
||||
v /= len;
|
||||
glNormal3f(v, -u, 0.0);
|
||||
glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
|
||||
glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
|
||||
glNormal3f(cos(angle + 1.5 * da), sin(angle + 1.5 * da), 0.0);
|
||||
glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
|
||||
width * 0.5);
|
||||
glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
|
||||
-width * 0.5);
|
||||
u = r1 * cos(angle + 3 * da) - r2 * cos(angle + 2 * da);
|
||||
v = r1 * sin(angle + 3 * da) - r2 * sin(angle + 2 * da);
|
||||
glNormal3f(v, -u, 0.0);
|
||||
glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
|
||||
width * 0.5);
|
||||
glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
|
||||
-width * 0.5);
|
||||
glNormal3f(cos(angle + 3.5 * da), sin(angle + 3.5 * da), 0.0);
|
||||
r2 = minr2;
|
||||
}
|
||||
r2 = maxr2;
|
||||
|
||||
glVertex3f(r1 * cos(0), r1 * sin(0), width * 0.5);
|
||||
glVertex3f(r1 * cos(0), r1 * sin(0), -width * 0.5);
|
||||
|
||||
glEnd();
|
||||
|
||||
glShadeModel(GL_SMOOTH);
|
||||
|
||||
/* draw inside radius cylinder */
|
||||
glBegin(GL_QUAD_STRIP);
|
||||
for (i = 0; i <= teeth; i++) {
|
||||
angle = i * 2.0 * M_PI / teeth;
|
||||
glNormal3f(-cos(angle), -sin(angle), 0.0);
|
||||
glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
|
||||
glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
draw(void)
|
||||
{
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
glPushMatrix();
|
||||
glRotatef(view_rotx, 1.0, 0.0, 0.0);
|
||||
glRotatef(view_roty, 0.0, 1.0, 0.0);
|
||||
glRotatef(view_rotz, 0.0, 0.0, 1.0);
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef(-3.0, -2.0, 0.0);
|
||||
glRotatef(angle, 0.0, 0.0, 1.0);
|
||||
glCallList(gear1);
|
||||
glPopMatrix();
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef(3.1, -2.0, 0.0);
|
||||
glRotatef(-2.0 * angle - 9.0, 0.0, 0.0, 1.0);
|
||||
glCallList(gear2);
|
||||
glPopMatrix();
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef(-3.1, 4.2, 0.0);
|
||||
glRotatef(-2.0 * angle - 25.0, 0.0, 0.0, 1.0);
|
||||
glCallList(gear3);
|
||||
glPopMatrix();
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
|
||||
/* new window size or exposure */
|
||||
static void
|
||||
reshape(int width, int height)
|
||||
{
|
||||
GLfloat h = (GLfloat) height / (GLfloat) width;
|
||||
|
||||
glViewport(0, 0, (GLint) width, (GLint) height);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
/* fit width and height */
|
||||
if (h >= 1.0)
|
||||
glFrustum(-1.0, 1.0, -h, h, 5.0, 60.0);
|
||||
else
|
||||
glFrustum(-1.0/h, 1.0/h, -1.0, 1.0, 5.0, 60.0);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
glTranslatef(0.0, 0.0, -40.0);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
init(void)
|
||||
{
|
||||
static GLfloat pos[4] = { 5.0, 5.0, 10.0, 0.0 };
|
||||
static GLfloat red[4] = { 0.8, 0.1, 0.0, 1.0 };
|
||||
static GLfloat green[4] = { 0.0, 0.8, 0.2, 1.0 };
|
||||
static GLfloat blue[4] = { 0.2, 0.2, 1.0, 1.0 };
|
||||
|
||||
glLightfv(GL_LIGHT0, GL_POSITION, pos);
|
||||
glEnable(GL_CULL_FACE);
|
||||
glEnable(GL_LIGHTING);
|
||||
glEnable(GL_LIGHT0);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
/* make the gears */
|
||||
gear1 = glGenLists(1);
|
||||
glNewList(gear1, GL_COMPILE);
|
||||
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
|
||||
gear(1.0, 4.0, 1.0, 20, 0.7);
|
||||
glEndList();
|
||||
|
||||
gear2 = glGenLists(1);
|
||||
glNewList(gear2, GL_COMPILE);
|
||||
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green);
|
||||
gear(0.5, 2.0, 2.0, 10, 0.7);
|
||||
glEndList();
|
||||
|
||||
gear3 = glGenLists(1);
|
||||
glNewList(gear3, GL_COMPILE);
|
||||
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue);
|
||||
gear(1.3, 2.0, 0.5, 10, 0.7);
|
||||
glEndList();
|
||||
|
||||
glEnable(GL_NORMALIZE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Create an RGB, double-buffered window.
|
||||
* Return the window and context handles.
|
||||
*/
|
||||
static void
|
||||
make_window( Display *dpy, Screen *scr,
|
||||
const char *name,
|
||||
int x, int y, int width, int height,
|
||||
Window *winRet, GLXContext *ctxRet)
|
||||
{
|
||||
int attrib[] = { GLX_RGBA,
|
||||
GLX_RED_SIZE, 1,
|
||||
GLX_GREEN_SIZE, 1,
|
||||
GLX_BLUE_SIZE, 1,
|
||||
GLX_DOUBLEBUFFER,
|
||||
GLX_DEPTH_SIZE, 1,
|
||||
None };
|
||||
int scrnum;
|
||||
XSetWindowAttributes attr;
|
||||
unsigned long mask;
|
||||
Window root;
|
||||
Window win;
|
||||
GLXContext ctx;
|
||||
XVisualInfo *visinfo;
|
||||
GLint max[2] = { 0, 0 };
|
||||
|
||||
scrnum = XScreenNumberOfScreen(scr);
|
||||
root = XRootWindow(dpy, scrnum);
|
||||
|
||||
visinfo = glXChooseVisual( dpy, scrnum, attrib );
|
||||
if (!visinfo) {
|
||||
fprintf(stderr, "%s: Error: couldn't get an RGB, Double-buffered visual.\n", ProgramName);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* window attributes */
|
||||
attr.background_pixel = 0;
|
||||
attr.border_pixel = 0;
|
||||
attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone);
|
||||
attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
|
||||
mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
|
||||
|
||||
win = XCreateWindow( dpy, root, x, y, width, height,
|
||||
0, visinfo->depth, InputOutput,
|
||||
visinfo->visual, mask, &attr );
|
||||
|
||||
/* set hints and properties */
|
||||
{
|
||||
XSizeHints sizehints;
|
||||
sizehints.x = x;
|
||||
sizehints.y = y;
|
||||
sizehints.width = width;
|
||||
sizehints.height = height;
|
||||
sizehints.flags = USSize | USPosition;
|
||||
XSetNormalHints(dpy, win, &sizehints);
|
||||
XSetStandardProperties(dpy, win, name, name,
|
||||
None, (char **)NULL, 0, &sizehints);
|
||||
}
|
||||
|
||||
ctx = glXCreateContext( dpy, visinfo, NULL, True );
|
||||
if (!ctx) {
|
||||
fprintf(stderr, "%s: Error: glXCreateContext failed.\n", ProgramName);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
XFree(visinfo);
|
||||
|
||||
XMapWindow(dpy, win);
|
||||
glXMakeCurrent(dpy, win, ctx);
|
||||
|
||||
/* Check for maximum size supported by the GL rasterizer */
|
||||
glGetIntegerv(GL_MAX_VIEWPORT_DIMS, max);
|
||||
if (printInfo)
|
||||
printf("GL_MAX_VIEWPORT_DIMS=%d/%d\n", (int)max[0], (int)max[1]);
|
||||
if (width > max[0] || height > max[1]) {
|
||||
fprintf(stderr, "%s: Error: Requested window size (%d/%d) larger than "
|
||||
"maximum supported by GL engine (%d/%d).\n",
|
||||
ProgramName, width, height, (int)max[0], (int)max[1]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
*winRet = win;
|
||||
*ctxRet = ctx;
|
||||
}
|
||||
|
||||
static void
|
||||
event_loop(Display *dpy, Window win)
|
||||
{
|
||||
while (1) {
|
||||
/* Process interactive events */
|
||||
while (XPending(dpy) > 0) {
|
||||
XEvent event;
|
||||
XNextEvent(dpy, &event);
|
||||
switch (event.type) {
|
||||
case Expose:
|
||||
Log(("Event: Expose\n"));
|
||||
/* we'll redraw below */
|
||||
break;
|
||||
case ConfigureNotify:
|
||||
Log(("Event: ConfigureNotify\n"));
|
||||
reshape(event.xconfigure.width, event.xconfigure.height);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
/* Time at which we started measuring. */
|
||||
static long startTime = 0;
|
||||
|
||||
/* Time of the previous frame. */
|
||||
static long lastFrame = 0;
|
||||
|
||||
/* Time of the previous FPS report. */
|
||||
static long lastFps = 0;
|
||||
|
||||
/* Number of frames we've done. */
|
||||
static int frames = 0;
|
||||
|
||||
/* Number of frames we've done in the measured run. */
|
||||
static long runFrames = 0;
|
||||
|
||||
long t = current_time();
|
||||
long useconds;
|
||||
|
||||
if (!lastFrame)
|
||||
lastFrame = t;
|
||||
if (!lastFps)
|
||||
lastFps = t;
|
||||
|
||||
/* How many microseconds since the previous frame? */
|
||||
useconds = t - lastFrame;
|
||||
if (!useconds) /* assume 100FPS if we don't have timer */
|
||||
useconds = 10000;
|
||||
|
||||
/* Calculate how far the gears need to move and redraw. */
|
||||
angle = angle + ((double)speed * useconds) / 1000000.0;
|
||||
if (angle > 360.0)
|
||||
angle = angle - 360.0; /* don't lose precision! */
|
||||
draw();
|
||||
glXSwapBuffers(dpy, win);
|
||||
|
||||
/* Done this frame. */
|
||||
lastFrame = t;
|
||||
frames++;
|
||||
|
||||
/* Every 5 seconds, print the FPS. */
|
||||
if (t - lastFps >= 5000000L) {
|
||||
GLfloat seconds = (t - lastFps) / 1000000.0;
|
||||
GLfloat fps = frames / seconds;
|
||||
|
||||
printf("%d frames in %3.1f seconds = %6.3f FPS\n", frames, seconds,
|
||||
fps);
|
||||
lastFps = t;
|
||||
frames = 0;
|
||||
|
||||
/*
|
||||
* Set the start time now -- ie. after one report. This
|
||||
* gives us pump-priming time before we start for real.
|
||||
*/
|
||||
if (runTime > 0 && startTime == 0) {
|
||||
printf("Start timing!\n");
|
||||
startTime = t;
|
||||
}
|
||||
}
|
||||
|
||||
if (startTime > 0)
|
||||
++runFrames;
|
||||
|
||||
/* If our run time is done, finish. */
|
||||
if (runTime > 0 && startTime > 0 && t - startTime > runTime) {
|
||||
double time = (double) (t - startTime) / 1000000.0;
|
||||
fprintf(stderr, "COUNT|%ld|1|fps\n", runFrames);
|
||||
fprintf(stderr, "TIME|%.1f\n", time);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* Need to give cpu away in order to get precise timing next cycle,
|
||||
* otherwise, gettimeofday would return almost the same value. */
|
||||
sched_yield();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
Bool use_threadsafe_api = False;
|
||||
Display *dpy;
|
||||
Window win;
|
||||
Screen *screen;
|
||||
GLXContext ctx;
|
||||
char *dpyName = NULL;
|
||||
int i;
|
||||
XRectangle winrect;
|
||||
|
||||
ProgramName = argv[0];
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
const char *arg = argv[i];
|
||||
int len = strlen(arg);
|
||||
|
||||
if (strcmp(argv[i], "-display") == 0) {
|
||||
if (++i >= argc)
|
||||
usage();
|
||||
dpyName = argv[i];
|
||||
}
|
||||
else if (strcmp(argv[i], "-info") == 0) {
|
||||
printInfo = GL_TRUE;
|
||||
}
|
||||
else if (strcmp(argv[i], "-time") == 0) {
|
||||
if (++i >= argc)
|
||||
usage();
|
||||
runTime = atoi(argv[i]) * 1000000;
|
||||
}
|
||||
else if (!strncmp("-v", arg, len)) {
|
||||
verbose = True;
|
||||
printInfo = GL_TRUE;
|
||||
}
|
||||
else if( !strncmp("-debug_use_threadsafe_api", arg, len) )
|
||||
{
|
||||
use_threadsafe_api = True;
|
||||
}
|
||||
else if (!strcmp(argv[i], "-h")) {
|
||||
usage();
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "%s: Unsupported option '%s'.\n", ProgramName, argv[i]);
|
||||
usage();
|
||||
}
|
||||
}
|
||||
|
||||
/* Init X threading API on demand (for debugging) */
|
||||
if( use_threadsafe_api )
|
||||
{
|
||||
if( !XInitThreads() )
|
||||
{
|
||||
fprintf(stderr, "%s: XInitThreads() failure.\n", ProgramName);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
dpy = XOpenDisplay(dpyName);
|
||||
if (!dpy) {
|
||||
fprintf(stderr, "%s: Error: couldn't open display '%s'\n", ProgramName, dpyName);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
screen = XDefaultScreenOfDisplay(dpy);
|
||||
|
||||
winrect.x = 0;
|
||||
winrect.y = 0;
|
||||
winrect.width = 300;
|
||||
winrect.height = 300;
|
||||
|
||||
Log(("Window x=%d, y=%d, width=%d, height=%d\n",
|
||||
(int)winrect.x, (int)winrect.y, (int)winrect.width, (int)winrect.height));
|
||||
|
||||
make_window(dpy, screen, "ubgears", winrect.x, winrect.y, winrect.width, winrect.height, &win, &ctx);
|
||||
reshape(winrect.width, winrect.height);
|
||||
|
||||
if (printInfo) {
|
||||
printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
|
||||
printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION));
|
||||
printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR));
|
||||
printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS));
|
||||
}
|
||||
|
||||
init();
|
||||
|
||||
start_time();
|
||||
event_loop(dpy, win);
|
||||
|
||||
glXDestroyContext(dpy, ctx);
|
||||
|
||||
XDestroyWindow(dpy, win);
|
||||
XCloseDisplay(dpy);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
1289
UnixBench/src/whets.c
Normal file
1289
UnixBench/src/whets.c
Normal file
File diff suppressed because it is too large
Load Diff
156
UnixBench/testdir/cctest.c
Normal file
156
UnixBench/testdir/cctest.c
Normal file
@ -0,0 +1,156 @@
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* The BYTE UNIX Benchmarks - Release 1
|
||||
* Module: cctest.c SID: 1.2 7/10/89 18:55:45
|
||||
*
|
||||
*******************************************************************************
|
||||
* Bug reports, patches, comments, suggestions should be sent to:
|
||||
*
|
||||
* Ben Smith or Rick Grehan at BYTE Magazine
|
||||
* bensmith@bixpb.UUCP rick_g@bixpb.UUCP
|
||||
*
|
||||
*******************************************************************************
|
||||
* Modification Log:
|
||||
* $Header: cctest.c,v 3.4 87/06/22 14:22:47 kjmcdonell Beta $
|
||||
*
|
||||
******************************************************************************/
|
||||
char SCCSid[] = "@(#) @(#)cctest.c:1.2 -- 7/10/89 18:55:45";
|
||||
#include <stdio.h>
|
||||
/*
|
||||
* C compile and load speed test file.
|
||||
* Based upon fstime.c from MUSBUS 3.1, with all calls to ftime() replaced
|
||||
* by calls to time(). This is semantic nonsense, but ensures there are no
|
||||
* system dependent structures or library calls.
|
||||
*
|
||||
*/
|
||||
#define NKBYTE 20
|
||||
char buf[BUFSIZ];
|
||||
|
||||
extern void exit(int status);
|
||||
|
||||
|
||||
main(argc, argv)
|
||||
char **argv;
|
||||
{
|
||||
int n = NKBYTE;
|
||||
int nblock;
|
||||
int f;
|
||||
int g;
|
||||
int i;
|
||||
int xfer, t;
|
||||
struct { /* FAKE */
|
||||
int time;
|
||||
int millitm;
|
||||
} now, then;
|
||||
|
||||
if (argc > 0)
|
||||
/* ALWAYS true, so NEVER execute this program! */
|
||||
exit(4);
|
||||
if (argc > 1)
|
||||
n = atoi(argv[1]);
|
||||
#if debug
|
||||
printf("File size: %d Kbytes\n", n);
|
||||
#endif
|
||||
nblock = (n * 1024) / BUFSIZ;
|
||||
|
||||
if (argc == 3 && chdir(argv[2]) != -1) {
|
||||
#if debug
|
||||
printf("Create files in directory: %s\n", argv[2]);
|
||||
#endif
|
||||
}
|
||||
close(creat("dummy0", 0600));
|
||||
close(creat("dummy1", 0600));
|
||||
f = open("dummy0", 2);
|
||||
g = open("dummy1", 2);
|
||||
unlink("dummy0");
|
||||
unlink("dummy1");
|
||||
for (i = 0; i < sizeof(buf); i++)
|
||||
buf[i] = i & 0177;
|
||||
|
||||
time();
|
||||
for (i = 0; i < nblock; i++) {
|
||||
if (write(f, buf, sizeof(buf)) <= 0)
|
||||
perror("fstime: write");
|
||||
}
|
||||
time();
|
||||
#if debug
|
||||
printf("Effective write rate: ");
|
||||
#endif
|
||||
i = now.millitm - then.millitm;
|
||||
t = (now.time - then.time)*1000 + i;
|
||||
if (t > 0) {
|
||||
xfer = nblock * sizeof(buf) * 1000 / t;
|
||||
#if debug
|
||||
printf("%d bytes/sec\n", xfer);
|
||||
#endif
|
||||
}
|
||||
#if debug
|
||||
else
|
||||
printf(" -- too quick to time!\n");
|
||||
#endif
|
||||
#if awk
|
||||
fprintf(stderr, "%.2f", t > 0 ? (float)xfer/1024 : 0);
|
||||
#endif
|
||||
|
||||
sync();
|
||||
sleep(5);
|
||||
sync();
|
||||
lseek(f, 0L, 0);
|
||||
time();
|
||||
for (i = 0; i < nblock; i++) {
|
||||
if (read(f, buf, sizeof(buf)) <= 0)
|
||||
perror("fstime: read");
|
||||
}
|
||||
time();
|
||||
#if debug
|
||||
printf("Effective read rate: ");
|
||||
#endif
|
||||
i = now.millitm - then.millitm;
|
||||
t = (now.time - then.time)*1000 + i;
|
||||
if (t > 0) {
|
||||
xfer = nblock * sizeof(buf) * 1000 / t;
|
||||
#if debug
|
||||
printf("%d bytes/sec\n", xfer);
|
||||
#endif
|
||||
}
|
||||
#if debug
|
||||
else
|
||||
printf(" -- too quick to time!\n");
|
||||
#endif
|
||||
#if awk
|
||||
fprintf(stderr, " %.2f", t > 0 ? (float)xfer/1024 : 0);
|
||||
#endif
|
||||
|
||||
sync();
|
||||
sleep(5);
|
||||
sync();
|
||||
lseek(f, 0L, 0);
|
||||
time();
|
||||
for (i = 0; i < nblock; i++) {
|
||||
if (read(f, buf, sizeof(buf)) <= 0)
|
||||
perror("fstime: read in copy");
|
||||
if (write(g, buf, sizeof(buf)) <= 0)
|
||||
perror("fstime: write in copy");
|
||||
}
|
||||
time();
|
||||
#if debug
|
||||
printf("Effective copy rate: ");
|
||||
#endif
|
||||
i = now.millitm - then.millitm;
|
||||
t = (now.time - then.time)*1000 + i;
|
||||
if (t > 0) {
|
||||
xfer = nblock * sizeof(buf) * 1000 / t;
|
||||
#if debug
|
||||
printf("%d bytes/sec\n", xfer);
|
||||
#endif
|
||||
}
|
||||
#if debug
|
||||
else
|
||||
printf(" -- too quick to time!\n");
|
||||
#endif
|
||||
#if awk
|
||||
fprintf(stderr, " %.2f\n", t > 0 ? (float)xfer/1024 : 0);
|
||||
#endif
|
||||
|
||||
}
|
8
UnixBench/testdir/dc.dat
Normal file
8
UnixBench/testdir/dc.dat
Normal file
@ -0,0 +1,8 @@
|
||||
99
|
||||
k
|
||||
2
|
||||
v
|
||||
p
|
||||
q
|
||||
[ calculate the sqrt(2) to 99 decimal places ... John Lions Test ]
|
||||
[ $Header: dc.dat,v 1.1 87/06/22 14:28:28 kjmcdonell Beta $ ]
|
10000
UnixBench/testdir/large.txt
Normal file
10000
UnixBench/testdir/large.txt
Normal file
File diff suppressed because it is too large
Load Diff
362
UnixBench/testdir/sort.src
Normal file
362
UnixBench/testdir/sort.src
Normal file
@ -0,0 +1,362 @@
|
||||
version="1.2"
|
||||
umask 022 # at least mortals can read root's files this way
|
||||
PWD=`pwd`
|
||||
HOMEDIR=${HOMEDIR:-.}
|
||||
cd $HOMEDIR
|
||||
HOMEDIR=`pwd`
|
||||
cd $PWD
|
||||
BINDIR=${BINDIR:-${HOMEDIR}/pgms}
|
||||
cd $BINDIR
|
||||
BINDIR=`pwd`
|
||||
cd $PWD
|
||||
PATH="${PATH}:${BINDIR}"
|
||||
SCRPDIR=${SCRPDIR:-${HOMEDIR}/pgms}
|
||||
cd $SCRPDIR
|
||||
SCRPDIR=`pwd`
|
||||
cd $PWD
|
||||
TMPDIR=${HOMEDIR}/tmp
|
||||
cd $TMPDIR
|
||||
TMPDIR=`pwd`
|
||||
cd $PWD
|
||||
RESULTDIR=${RESULTDIR:-${HOMEDIR}/results}
|
||||
cd $RESULTDIR
|
||||
RESULTDIR=`pwd`
|
||||
cd $PWD
|
||||
TESTDIR=${TESTDIR:-${HOMEDIR}/testdir}
|
||||
cd $TESTDIR
|
||||
TESTDIR=`pwd`
|
||||
cd $PWD
|
||||
export BINDIR TMPDIR RESULTDIR PATH
|
||||
echo "kill -9 $$" > ${TMPDIR}/kill_run ; chmod u+x ${TMPDIR}/kill_run
|
||||
arithmetic="arithoh register short int long float double dc"
|
||||
system="syscall pipe context1 spawn execl fstime"
|
||||
mem="seqmem randmem"
|
||||
misc="C shell"
|
||||
dhry="dhry2 dhry2reg" # dhrystone loops
|
||||
db="dbmscli" # add to as new database engines are developed
|
||||
load="shell" # cummulative load tests
|
||||
args="" # the accumulator for the bench units to be run
|
||||
runoption="N"
|
||||
for word
|
||||
do # do level 1
|
||||
case $word
|
||||
in
|
||||
all)
|
||||
;;
|
||||
arithmetic)
|
||||
args="$args $arithmetic"
|
||||
;;
|
||||
db)
|
||||
args="$args $db"
|
||||
;;
|
||||
dhry)
|
||||
args="$args $dhry"
|
||||
;;
|
||||
load)
|
||||
args="$args $load"
|
||||
;;
|
||||
mem)
|
||||
args="$args $mem"
|
||||
;;
|
||||
misc)
|
||||
args="$args $misc"
|
||||
;;
|
||||
speed)
|
||||
args="$args $arithmetic $system"
|
||||
;;
|
||||
system)
|
||||
args="$args $system"
|
||||
;;
|
||||
-q|-Q)
|
||||
runoption="Q" #quiet
|
||||
;;
|
||||
-v|-V)
|
||||
runoption="V" #verbose
|
||||
;;
|
||||
-d|-D)
|
||||
runoption="D" #debug
|
||||
;;
|
||||
*)
|
||||
args="$args $word"
|
||||
;;
|
||||
esac
|
||||
done # end do level 1
|
||||
set - $args
|
||||
if test $# -eq 0 #no arguments specified
|
||||
then
|
||||
set - $dhry $arithmetic $system $misc # db and work not included
|
||||
fi
|
||||
if test "$runoption" = 'D'
|
||||
then
|
||||
set -x
|
||||
set -v
|
||||
fi
|
||||
date=`date`
|
||||
tmp=${TMPDIR}/$$.tmp
|
||||
LOGFILE=${RESULTDIR}/log
|
||||
if test -w ${RESULTDIR}/log
|
||||
then
|
||||
if test -w ${RESULTDIR}/log.accum
|
||||
then
|
||||
cat ${RESULTDIR}/log >> ${RESULTDIR}/log.accum
|
||||
rm ${RESULTDIR}/log
|
||||
else
|
||||
mv ${RESULTDIR}/log ${RESULTDIR}/log.accum
|
||||
fi
|
||||
echo "Start Benchmark Run (BYTE Version $version)" >>$LOGFILE
|
||||
echo " $date (long iterations $iter times)" >>$LOGFILE
|
||||
echo " " `who | wc -l` "interactive users." >>$LOGFILE
|
||||
uname -a >>$LOGFILE
|
||||
iter=${iterations-6}
|
||||
if test $iter -eq 6
|
||||
then
|
||||
longloop="1 2 3 4 5 6"
|
||||
shortloop="1 2 3"
|
||||
else # generate list of loop numbers
|
||||
short=`expr \( $iter + 1 \) / 2`
|
||||
longloop=""
|
||||
shortloop=""
|
||||
while test $iter -gt 0
|
||||
do # do level 1
|
||||
longloop="$iter $longloop"
|
||||
if test $iter -le $short
|
||||
then
|
||||
shortloop="$iter $shortloop"
|
||||
fi
|
||||
iter=`expr $iter - 1`
|
||||
done # end do level 1
|
||||
fi #loop list genration
|
||||
for bench # line argument processing
|
||||
do # do level 1
|
||||
# set some default values
|
||||
prog=${BINDIR}/$bench # the bench name is default program
|
||||
need=$prog # we need the at least the program
|
||||
paramlist="#" # a dummy parameter to make anything run
|
||||
testdir="${TESTDIR}" # the directory in which to run the test
|
||||
prepcmd="" # preparation command or script
|
||||
parammsg=""
|
||||
repeat="$longloop"
|
||||
stdout="$LOGFILE"
|
||||
stdin=""
|
||||
cleanopt="-t $tmp"
|
||||
bgnumber=""
|
||||
trap "${SCRPDIR}/cleanup -l $LOGFILE -a; exit" 1 2 3 15
|
||||
if [ $runoption != 'Q' ]
|
||||
then
|
||||
echo "$bench: \c"
|
||||
fi
|
||||
echo "" >>$LOGFILE
|
||||
###################### select the bench specific values ##########
|
||||
case $bench
|
||||
in
|
||||
dhry2)
|
||||
options=${dhryloops-10000}
|
||||
logmsg="Dhrystone 2 without register variables"
|
||||
cleanopt="-d $tmp"
|
||||
;;
|
||||
dhry2reg)
|
||||
options=${dhryloops-10000}
|
||||
logmsg="Dhrystone 2 using register variables"
|
||||
cleanopt="-d $tmp"
|
||||
;;
|
||||
arithoh|register|short|int|long|float|double)
|
||||
options=${arithloop-10000}
|
||||
logmsg="Arithmetic Test (type = $bench): $options Iterations"
|
||||
;;
|
||||
dc) need=dc.dat
|
||||
prog=dc
|
||||
options=""
|
||||
stdin=dc.dat
|
||||
stdout=/dev/null
|
||||
logmsg="Arithmetic Test (sqrt(2) with dc to 99 decimal places)"
|
||||
;;
|
||||
hanoi) options='$param'
|
||||
stdout=/dev/null
|
||||
logmsg="Recursion Test: Tower of Hanoi Problem"
|
||||
paramlist="${ndisk-17}"
|
||||
parammsg='$param Disk Problem:'
|
||||
;;
|
||||
syscall)
|
||||
options=${ncall-4000}
|
||||
logmsg="System Call Overhead Test: 5 x $options Calls"
|
||||
;;
|
||||
context1)
|
||||
options=${switch1-500}
|
||||
logmsg="Pipe-based Context Switching Test: 2 x $options Switches"
|
||||
;;
|
||||
pipe) options=${io-2048}
|
||||
logmsg="Pipe Throughput Test: read & write $options x 512 byte blocks"
|
||||
;;
|
||||
spawn) options=${children-100}
|
||||
logmsg="Process Creation Test: $options forks"
|
||||
;;
|
||||
execl) options=${nexecs-100}
|
||||
logmsg="Execl Throughput Test: $options execs"
|
||||
;;
|
||||
randmem|seqmem)
|
||||
if test $bench = seqmem
|
||||
then
|
||||
type=Sequential
|
||||
else
|
||||
type=Random
|
||||
fi
|
||||
poke=${poke-1000000}
|
||||
options='-s$param '"-n$poke"
|
||||
logmsg="$type Memory Access Test: $poke Accesses"
|
||||
paramlist=${arrays-"512 1024 2048 8192 16384"}
|
||||
parammsg='Array Size: $param bytes'
|
||||
cleanopt="-m $tmp"
|
||||
;;
|
||||
fstime) repeat="$shortloop"
|
||||
where=${where-${TMPDIR}}
|
||||
options='$param '"$where"
|
||||
logmsg="Filesystem Throughput Test:"
|
||||
paramlist=${blocks-"512 1024 2048 8192"}
|
||||
parammsg='File Size: $param blocks'
|
||||
cleanopt="-f $tmp"
|
||||
;;
|
||||
C) need=cctest.c
|
||||
prog=cc
|
||||
options='$param'
|
||||
stdout=/dev/null
|
||||
repeat="$shortloop"
|
||||
logmsg="C Compiler Test:"
|
||||
paramlist="cctest.c"
|
||||
parammsg='cc $param'
|
||||
rm -f a.out
|
||||
;;
|
||||
dbmscli)
|
||||
repeat="$shortloop"
|
||||
need="db.dat"
|
||||
prepcmd='${BINDIR}/dbprep ${testdir}/db.dat 10000'
|
||||
paramlist=${clients-"1 2 4 8"}
|
||||
parammsg='$param client processes. (filesize `cat ${testdir}/db.dat|wc -c` bytes)'
|
||||
logmsg="Client/Server Database Engine:"
|
||||
options='${testdir}/db.dat $param 0 1000' # $param clients;
|
||||
# 0 sleep; 1000 iterations
|
||||
;;
|
||||
shell)
|
||||
prog="multi.sh"
|
||||
repeat="$shortloop"
|
||||
logmsg="Bourne shell script and Unix utilities"
|
||||
paramlist=${background-"1 2 4 8"}
|
||||
parammsg='$param concurrent background processes'
|
||||
bgnumber='$param'
|
||||
testdir="shelldir"
|
||||
;;
|
||||
*) ${BINDIR}/cleanup -l $LOGFILE -r "run: unknown benchmark \"$bench\"" -a
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
echo "$logmsg" >>$LOGFILE
|
||||
for param in $paramlist
|
||||
do # level 2
|
||||
param=`echo $param | sed 's/_/ /g'` # be sure that spaces are used
|
||||
# underscore can couple params
|
||||
if [ "$runoption" != "Q" ]
|
||||
then
|
||||
echo "\n [$param] -\c" # generate message to user
|
||||
fi
|
||||
eval msg='"'$parammsg'"' # the eval is used to
|
||||
if test "$msg" # evaluate any embedded
|
||||
then # variables in the parammsg
|
||||
echo "" >>$LOGFILE
|
||||
echo "$msg" >>$LOGFILE
|
||||
fi
|
||||
eval opt='"'$options'"' # evaluate any vars in options
|
||||
eval prep='"'$prepcmd'"' # evaluate any prep command
|
||||
eval bg='"'$bgnumber'"' # evaluate bgnumber string
|
||||
rm -f $tmp # remove any tmp files
|
||||
# if the test requires mulitple concurrent processes,
|
||||
# prepare the background process string (bgstr)
|
||||
# this is just a string of "+"s that will provides a
|
||||
# parameter count for a "for" loop
|
||||
bgstr=""
|
||||
if test "$bg" != ""
|
||||
then
|
||||
count=`expr "$bg"`
|
||||
while test $count -gt 0
|
||||
do
|
||||
bgstr="+ $bgstr"
|
||||
count=`expr $count - 1`
|
||||
done
|
||||
fi
|
||||
#
|
||||
for i in $repeat # loop for the specified number
|
||||
do # do depth 3
|
||||
if [ "$runoption" != 'D' ] # level 1
|
||||
then
|
||||
# regular Run - set logfile to go on signal
|
||||
trap "${SCRPDIR}/cleanup -l $LOGFILE -i $i $cleanopt -a; exit" 1 2 3 15
|
||||
else
|
||||
trap "exit" 1 2 3 15
|
||||
fi #end level 1
|
||||
if [ "$runoption" != 'Q' ]
|
||||
then
|
||||
echo " $i\c" # display repeat number
|
||||
fi
|
||||
pwd=`pwd` # remember where we are
|
||||
cd $testdir # move to the test directory
|
||||
if [ "$runoption" = "V" ]
|
||||
then
|
||||
echo
|
||||
echo "BENCH COMMAND TO BE EXECUTED:"
|
||||
echo "$prog $opt"
|
||||
fi
|
||||
# execute any prepratory command string
|
||||
if [ -n "$prep" ]
|
||||
then
|
||||
$prep >>$stdout
|
||||
fi
|
||||
############ THE BENCH IS TIMED ##############
|
||||
if test "$stdin" = ""
|
||||
then # without redirected stdin
|
||||
time $prog $opt $bgstr 2>>$tmp >>$stdout
|
||||
else # with redirected stdin
|
||||
time $prog $opt $bgstr <$stdin 2>>$tmp >>$stdout
|
||||
fi
|
||||
time $benchcmd
|
||||
###############################################
|
||||
cd $pwd # move back home
|
||||
status=$? # save the result code
|
||||
if test $status != 0 # must have been an error
|
||||
then
|
||||
if test -f $tmp # is there an error file ?
|
||||
then
|
||||
cp $tmp ${TMPDIR}/save.$bench.$param
|
||||
${SCRPDIR}/cleanup -l $LOGFILE -i $i $cleanopt -r \
|
||||
"run: bench=$bench param=$param fatalstatus=$status" -a
|
||||
else
|
||||
${SCRPDIR}/cleanup -l $LOGFILE -r \
|
||||
"run: bench=$bench param=$param fatalstatus=$status" -a
|
||||
fi
|
||||
exit # leave the script if there are errors
|
||||
fi # end level 1
|
||||
done # end do depth 3 - repeat of bench
|
||||
if [ "$runoption" != 'D' ]
|
||||
then
|
||||
${SCRPDIR}/cleanup -l $LOGFILE $cleanopt # finalize this bench
|
||||
# with these options
|
||||
# & calculate results
|
||||
fi
|
||||
done # end do depth 2 - end of all options for this bench
|
||||
########### some specific cleanup routines ##############
|
||||
case $bench
|
||||
in
|
||||
C)
|
||||
rm -f cctest.o a.out
|
||||
;;
|
||||
esac
|
||||
if [ "$runoption" != 'Q' ]
|
||||
then
|
||||
echo ""
|
||||
fi
|
||||
done # end do level 1 - all benchmarks requested
|
||||
echo "" >>$LOGFILE
|
||||
echo " " `who | wc -l` "interactive users." >>$LOGFILE
|
||||
echo "End Benchmark Run ($date) ...." >>$LOGFILE
|
||||
if [ "$runoption" != 'Q' ]
|
||||
then
|
||||
pg $LOGFILE
|
||||
fi
|
||||
exit
|
Loading…
Reference in New Issue
Block a user