perf_index - This is a tool for gather performance data. perf_index can run in two modes. In regulular (offline mode) the usage is: pref_index type threads size [args] where type is one of the test types explained below, threads is the number of userland threads that should preform the task, size is the size of the task and args are arguments to pass to the test. Currently only the iperf test requires these arguments. For example if run with the following arguments: ./perf_index cpu 2 100000000 iperf will run the cpu workload on two threads with a total work load size of 100000000. Since the workload is distributed over 2 threads, on a perfectly parallel system, this would take half the time relative to if 1 was specified for the threads parameter. When finished running perf_index will write the number of seconds it took to standard out as a decimal number. Some of the test types have initialization and teardown steps, and these steps are not counted towards the time. The workload and the time it takes to be performed differs quite drastically between test type, so you may need to play around with the size argument to find a value that will complete in a reasonable amount of time. In online mode, perf_index is invoked like so: perf_index remote server where remote is exactly the string "remote" and server is the control host to connect to. This tells the program to connect to the specified server and wait for instructions. The server is run by running the test_controller.py python script with the following arguments: test_controller.py num_clients type threads size The server will wait for num_client to connect. It will then pass type, threads, and size to each of those clients, who will run the initialization code and report back to the server. Once the initialization is run by every client, the server will give the OK to every client to run the workload and begin timing. When done, each client reports back to the server. Once the server hears back from every client, it will stop timing and output the elapsed time. Test Types: Note this implementations are subject to change, for an authoritative source, see the source code cpu - calculates n md5 sums memory - initializes by allocating memory equal to half the RAM on the machine, then writes a byte to every page to ensure it is paged in. Then copies n bytes from the first half of memory to the second. If the allocated space is less than n/2, it keeps repeating the copies until n bytes are copied. syscall - calls the getppid(2) system call n times fault - performs n page faults by mmaping a large chunk of memory, toggling the write protection bit, and writing to each page zfod - performs n zero fill on demands, by mmaping a large chunk of memory and writing to each page file_create - creates n files (in the same directory) with the open(2) system call file_write - writes n bytes to files on disk. There is one file per each thread. file_read - initializes by creating one large file on disk per each thread. Then reads n bytes total from all the files. If there are less than n bytes in the files, repeats reading from the beginning. ram_file_create - same as file_create but on a ram disk ram_file_read - same as file_read but on a ram disk ram_file_write - same as file_write but on a ram disk iperf - uses iperf to send n bytes over the network to the designated host specified as args compile - compiles xnu using make. This currently does a single compile and ignores the size argument Building: perf_index is built automatically by BNI for both Mac (10.9 and later), and iOS (7 and later) trains, and is delivered on AppleInternal builds in /AppleInternal/CoreOS/perf_index. It is built as part of the xnu_quick_test build alias, so you can also find a copy on ~rc at: ~rc/Software/$RELEASE/Updates/$RELEASEVERSION/Roots/xnu_quick_test/AppleInternal/CoreOS/perf_index. Alternatively you can build it yourself using make like so: SDKROOT=/path/to/sdk make For example: # build for Mac, current OS SDKROOT=/ make # build for iOS SDKROOT=`xcodebuild -sdk iphoneos.internal -version Path` make By default xnu builds all-way fat, but you can restrict this by explicitly specifying architectures like so: # build for only armv7 and armv7s SDKROOT=`xcodebuild -sdk iphoneos.internal -version Path` make ARCH="armv7 armv7s"