author | Tong Li <tong.li@amlogic.com> | 2018-01-08 06:13:43 (GMT) |
---|---|---|
committer | Tong Li <tong.li@amlogic.com> | 2018-01-08 06:17:41 (GMT) |
commit | bf0f51dd9ef304db5152dcf0fb3b8296e67e7759 (patch) | |
tree | a937655b3fb24ab77189aa04f6ecf7f38cf11d15 | |
parent | 1069c6c39759979b704e828d8943d2c0bde8c195 (diff) | |
download | tools-bf0f51dd9ef304db5152dcf0fb3b8296e67e7759.zip tools-bf0f51dd9ef304db5152dcf0fb3b8296e67e7759.tar.gz tools-bf0f51dd9ef304db5152dcf0fb3b8296e67e7759.tar.bz2 |
PD#NONE: add cpuburn.[1/1]
Change-Id: Ic37c38e0b3751c7635c899af700ac42c6040302c
-rw-r--r-- | cpuburn/Android.mk | 25 | ||||
-rw-r--r-- | cpuburn/README.md | 4 | ||||
-rw-r--r-- | cpuburn/cpuburn-a53.S | 183 | ||||
-rw-r--r-- | cpuburn/cpuburn-a7.S | 91 | ||||
-rw-r--r-- | cpuburn/cpuburn-a8.S | 73 | ||||
-rw-r--r-- | cpuburn/cpuburn-a9.S | 97 | ||||
-rw-r--r-- | cpuburn/cpuburn-krait.S | 96 | ||||
-rw-r--r-- | cpuburn/cpufreq-ljt-stress-test | 217 | ||||
-rw-r--r-- | cpuburn/gnuplot-sunxi-cpufreq | 112 |
9 files changed, 898 insertions, 0 deletions
diff --git a/cpuburn/Android.mk b/cpuburn/Android.mk new file mode 100644 index 0000000..e47b258 --- a/dev/null +++ b/cpuburn/Android.mk @@ -0,0 +1,25 @@ +# Copyright 2006 The Android Open Source Project + +# XXX using libutils for simulator build only... +# +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES:= \ + cpuburn-a53.S \ + +LOCAL_STATIC_LIBRARIES:= \ + libcutils \ + libc + + +LOCAL_C_INCLUDES := $(KERNEL_HEADERS) +LOCAL_MODULE_TAGS := eng + +LOCAL_ARM_MODE := arm + +LOCAL_FORCE_STATIC_EXECUTABLE := true + +LOCAL_LDLIBS += -lpthread +LOCAL_MODULE:= cpuburn-a53 +include $(BUILD_EXECUTABLE) diff --git a/cpuburn/README.md b/cpuburn/README.md new file mode 100644 index 0000000..3fd963b --- a/dev/null +++ b/cpuburn/README.md @@ -0,0 +1,4 @@ +cpuburn +======= + +A collection of cpuburn programs tuned for different ARM hardware diff --git a/cpuburn/cpuburn-a53.S b/cpuburn/cpuburn-a53.S new file mode 100644 index 0000000..2b50295 --- a/dev/null +++ b/cpuburn/cpuburn-a53.S @@ -0,0 +1,183 @@ +/* + * Copyright © 2016 Siarhei Siamashka <siarhei.siamashka@gmail.com> + * + * 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 (including the next + * paragraph) 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 + * THE AUTHORS OR COPYRIGHT HOLDERS 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. + */ + +/* + * This program tries to stress ARM Cortex-A53 processor to generate as + * much heat as possible. + * WARNING: improperly cooled or otherwise flawed hardware may potentially + * overheat and fail. Use at your own risk. + * + * Compilation instructions: + * $ aarch64-linux-gnu-gcc -o cpuburn-a53 cpuburn-a53.S + * or + * $ arm-linux-gnueabihf-gcc -o cpuburn-a53 cpuburn-a53.S + * + * See http://ssvb.github.io/2012/04/10/cpuburn-arm-cortex-a9.html + * for more details. + */ + +#define LOOP_UNROLL_FACTOR 100 + +#ifdef __aarch64__ + +/****************************************************************************/ +/* 64-bit implementation */ +/****************************************************************************/ + + .cpu cortex-a53+fp+simd + .text + .align 2 + .global main + .type main, %function + +main: + stp x29, x30, [sp, #-16]! + +#ifdef __linux__ + mov w0, #84 /* _SC_NPROCESSORS_ONLN */ + bl sysconf + mov w29, w0 + cmp w29, #2 + blt 1f + bl fork /* have at least 2 cores */ + cmp w29, #4 + blt 1f + bl fork /* have at least 4 cores */ + cmp w29, #8 + blt 1f + bl fork /* have at least 8 cores */ +1: +#endif + + movi v28.16b, #0xff + movi v29.16b, #0xff + movi v30.16b, #0xff + movi v31.16b, #0xff + + adr x4, 9f + add x4, x4, #1 + mov x1, #0 + mov x2, #(64 / 4) + + b 0f + + .ltorg +9: + .rept 64 + .long 0xffffffff + .endr + + .balign 64 +0: + .rept LOOP_UNROLL_FACTOR + uaba v8.4s, v28.4s, v29.4s + bne 1f +1: uaba v9.4s, v30.4s, v31.4s + ldr w0, [x4, x1, lsl #2] + uaba v10.4s, v28.4s, v29.4s + bne 1f +1: uaba v11.4s, v30.4s, v31.4s + ldr w0, [x4, x2, lsl #2] + .endr + b 0b + + mov w0, #0 + ldp x29, x30, [sp], #16 + ret + +/****************************************************************************/ + +#else + +/****************************************************************************/ +/* 32-bit implementation */ +/****************************************************************************/ + + .syntax unified + .text + .arch armv7-a + .fpu neon + .global main + .type main, %function + .align 2 + .arm + +main: + push {r4-r12, lr} + vpush {q8-q15} + +#ifdef __linux__ + mov r0, 84 /* _SC_NPROCESSORS_ONLN */ + bl sysconf + mov r4, r0 + cmp r4, #2 + blt 1f + bl fork /* have at least 2 cores */ + cmp r4, #4 + blt 1f + bl fork /* have at least 4 cores */ + cmp r4, #8 + blt 1f + bl fork /* have at least 8 cores */ +1: +#endif + + vmov.u8 q12, #0xff + vmov.u8 q13, #0xff + vmov.u8 q14, #0xff + vmov.u8 q15, #0xff + + adr lr, 9f + add lr, lr, #1 + mov r1, #(64 / 4) + mov r2, #(-64 / 4) + + b 0f + + .ltorg +9: + .rept 64 + .long 0xffffffff + .endr + + .balign 64 +0: + .rept LOOP_UNROLL_FACTOR + vaba.u32 q8, q12, q13 + bne 1f +1: vaba.u32 q9, q14, q15 + ldrne r0, [lr, r1, lsl #2]! + vaba.u32 q10, q12, q13 + bne 1f +1: vaba.u32 q11, q14, q15 + ldrne r0, [lr, r2, lsl #2]! + .endr + b 0b + + vpop {q8-q15} + mov r0, #0 + pop {r4-r12, pc} + +/****************************************************************************/ + +#endif diff --git a/cpuburn/cpuburn-a7.S b/cpuburn/cpuburn-a7.S new file mode 100644 index 0000000..74e925a --- a/dev/null +++ b/cpuburn/cpuburn-a7.S @@ -0,0 +1,91 @@ +/* + * Copyright © 2013 Siarhei Siamashka <siarhei.siamashka@gmail.com> + * + * 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 (including the next + * paragraph) 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 + * THE AUTHORS OR COPYRIGHT HOLDERS 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. + */ + +/* + * This program tries to stress ARM Cortex-A7 processor to generate as + * much heat as possible. + * WARNING: improperly cooled or otherwise flawed hardware may potentially + * overheat and fail. Use at your own risk. + * + * Compilation instructions: + * $ arm-linux-gnueabihf-gcc -o cpuburn-a7 cpuburn-a7.S + * + * See http://ssvb.github.io/2012/04/10/cpuburn-arm-cortex-a9.html + * for more details. + */ + + .syntax unified + .text + .arch armv7-a + .fpu neon + .arm + + .global main + +.func main +.type main, %function +main: + push {r4-r12, lr} + +#ifdef __linux__ + mov r0, 84 /* _SC_NPROCESSORS_ONLN */ + bl sysconf + mov r4, r0 + cmp r4, #2 + blt 1f + bl fork /* have at least 2 cores */ + cmp r4, #4 + blt 1f + bl fork /* have at least 4 cores */ + cmp r4, #8 + blt 1f + bl fork /* have at least 8 cores */ +1: +#endif + + adr lr, 9f + add lr, lr, #129 + mov r1, #(64 / 4) + mov r2, #(-64 / 4) + mov ip, #1 + b 0f + + .balign 64 +9: + .rept 128 + .long 0xffffffff + .endr + + .balign 64 +/****************************************************************************/ +/* Main loop (2 cycles per loop iteration, reaching peak IPC=2) */ +/****************************************************************************/ +0: ldrne r0, [lr, r1, lsl #2] + subs ip, ip, #0 + + ldrne r0, [lr, r2, lsl #2] + bne 0b + + mov r0, #0 + pop {r4-r12, pc} +.endfunc diff --git a/cpuburn/cpuburn-a8.S b/cpuburn/cpuburn-a8.S new file mode 100644 index 0000000..c6f93a6 --- a/dev/null +++ b/cpuburn/cpuburn-a8.S @@ -0,0 +1,73 @@ +/* + * Copyright © 2012 Siarhei Siamashka <siarhei.siamashka@gmail.com> + * + * 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 (including the next + * paragraph) 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 + * THE AUTHORS OR COPYRIGHT HOLDERS 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. + */ + +/* + * This program tries to stress ARM Cortex-A8 processor to generate as + * much heat as possible. + * WARNING: improperly cooled or otherwise flawed hardware may potentially + * overheat and fail. Use at your own risk. + * + * Compilation instructions: + * $ arm-linux-gnueabihf-gcc -o cpuburn-a8 cpuburn-a8.S + * + * See http://ssvb.github.com/2012/04/10/cpuburn-arm-cortex-a9.html + * for more details. + */ + .syntax unified + .text + .arch armv7-a + .fpu neon + .thumb + + .global main + +/* optimal value for LOOP_UNROLL_FACTOR seems to be BTB size dependent */ +#define LOOP_UNROLL_FACTOR 130 +/* 16 seems to be a good choice */ +#define STEP 16 + +.func main +.thumb_func +main: + mov lr, pc + adds lr, lr, #63 + bic lr, lr, #63 + mov ip, #STEP + .p2align 2 +0: + .rept LOOP_UNROLL_FACTOR + vld2.8 {q0}, [lr, :128], ip + vaba.u8 q4, q4, q3 + bne 1f +1: vld2.8 {q1}, [lr, :128], ip + vaba.u8 q5, q5, q0 + vld2.8 {q2}, [lr, :128], ip + vaba.u8 q6, q6, q1 + bne 1f +1: vld2.8 {q3}, [lr, :128], ip + vaba.u8 q7, q7, q2 + smuad r0, r1, r2 + subs lr, lr, #(STEP * 4) + .endr + bne 0b +.endfunc diff --git a/cpuburn/cpuburn-a9.S b/cpuburn/cpuburn-a9.S new file mode 100644 index 0000000..0338b00 --- a/dev/null +++ b/cpuburn/cpuburn-a9.S @@ -0,0 +1,97 @@ +/* + * Copyright © 2012 Siarhei Siamashka <siarhei.siamashka@gmail.com> + * + * 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 (including the next + * paragraph) 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 + * THE AUTHORS OR COPYRIGHT HOLDERS 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. + */ + +/* + * This program tries to stress ARM Cortex-A9 processor to generate as + * much heat as possible. Needs NEON, so does not work on Tegra 2. + * WARNING: improperly cooled or otherwise flawed hardware may potentially + * overheat and fail. Use at your own risk. + * + * Compilation instructions: + * $ arm-linux-gnueabihf-gcc -o cpuburn-a9 cpuburn-a9.S + * + * See http://ssvb.github.com/2012/04/10/cpuburn-arm-cortex-a9.html + * for more details. + */ + .syntax unified + .text + .arch armv7-a + .fpu neon + .arm + + .global main + .global sysconf + .global fork + +/* optimal value for LOOP_UNROLL_FACTOR seems to be BTB size dependent */ +#define LOOP_UNROLL_FACTOR 110 +/* 64 seems to be a good choice */ +#define STEP 64 + +.func main +.type main, %function +main: + +#ifdef __linux__ + mov r0, 84 /* _SC_NPROCESSORS_ONLN */ + blx sysconf + mov r4, r0 + cmp r4, #2 + blt 1f + blx fork /* have at least 2 cores */ + cmp r4, #4 + blt 1f + blx fork /* have at least 4 cores */ +1: +#endif + + ldr lr, =(STEP * 4 + 15) + subs lr, sp, lr + bic lr, lr, #15 + mov ip, #STEP + mov r0, #0 + mov r1, #0 + mov r2, #0 + mov r3, #0 + ldr r4, =0xFFFFFFFF + b 0f + .ltorg +0: + .rept LOOP_UNROLL_FACTOR + vld2.8 {q0}, [lr, :128], ip + it ne + smlalne r0, r1, lr, r4 + bne 1f +1: + vld2.8 {q1}, [lr, :128], ip + it ne + smlalne r2, r3, lr, r4 + bne 1f +1: + vld2.8 {q2}, [lr, :128], ip + vld2.8 {q3}, [lr, :128], ip + it ne + subsne lr, lr, #(STEP * 4) + .endr + bne 0b +.endfunc diff --git a/cpuburn/cpuburn-krait.S b/cpuburn/cpuburn-krait.S new file mode 100644 index 0000000..02f8c73 --- a/dev/null +++ b/cpuburn/cpuburn-krait.S @@ -0,0 +1,96 @@ +/* + * Copyright © 2016 Siarhei Siamashka <siarhei.siamashka@gmail.com> + * + * 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 (including the next + * paragraph) 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 + * THE AUTHORS OR COPYRIGHT HOLDERS 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. + */ + +/* + * This program tries to stress Qualcomm Krait 300/400 processor to generate + * as much heat as possible. + * WARNING: improperly cooled or otherwise flawed hardware may potentially + * overheat and fail. Use at your own risk. + * + * Compilation instructions: + * $ arm-linux-gnueabihf-gcc -o cpuburn-krait cpuburn-krait.S + * + * See http://ssvb.github.io/2012/04/10/cpuburn-arm-cortex-a9.html + * for more details. + */ + + .syntax unified + .text + .arch armv7-a + .fpu neon + .global main + .type main, %function + .align 2 + .arm + +main: + push {r4-r12, lr} + +#ifdef __linux__ + mov r0, #84 /* _SC_NPROCESSORS_ONLN */ + bl sysconf + mov r4, r0 + cmp r4, #2 + blt 1f + bl fork /* have at least 2 cores */ + cmp r4, #4 + blt 1f + bl fork /* have at least 4 cores */ + cmp r4, #8 + blt 1f + bl fork /* have at least 8 cores */ +1: +#endif + vmov.u8 q8, #0x0 + vmov.u8 q9, #0x0 + vmov.u8 q14, #0xff + vmov.u8 q15, #0xff + + adr lr, 9f + mov r1, #16 + mov r2, #-16 + mov ip, #1 + b 0f + + .balign 64 +9: + .rept 64 + .long 0xffffffff + .endr + + .balign 64 +/****************************************************************************/ +/* Main loop (2 cycles per loop iteration, reaching peak IPC=3) */ +/****************************************************************************/ +0: vld2.8 {q1}, [lr, :128], r1 + vaba.u8 q8, q2, q14 + + vld2.8 {q2}, [lr, :128], r2 + vaba.u8 q9, q1, q15 + + subs ip, ip, #0 + bne 0b +/****************************************************************************/ + + mov r0, #0 + pop {r4-r12, pc} diff --git a/cpuburn/cpufreq-ljt-stress-test b/cpuburn/cpufreq-ljt-stress-test new file mode 100644 index 0000000..dc3f93e --- a/dev/null +++ b/cpuburn/cpufreq-ljt-stress-test @@ -0,0 +1,217 @@ +#!/usr/bin/env ruby +# +# Copyright © 2014 Siarhei Siamashka <siarhei.siamashka@gmail.com> +# +# 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 (including the next +# paragraph) 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 +# THE AUTHORS OR COPYRIGHT HOLDERS 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. + +raise "Please upgrade ruby to at least version 1.9" if RUBY_VERSION =~ /^1\.8/ + +require 'shellwords' + +# Test the availability of the required tools + +def tool_exists(tool_name) + `which #{tool_name} > /dev/null 2>&1` + if $?.to_i != 0 then + printf("Error: the required '%s' executable is not found in PATH\n", tool_name) + return false + else + return true + end +end + +exit(1) if not tool_exists("md5sum") or + not tool_exists("nproc") or + not tool_exists("taskset") + +$cjpeg = "cjpeg" +$djpeg = "djpeg" + +def download_and_compile_libjpeg_turbo() + exit(1) if not tool_exists("wget") or + not tool_exists("tar") or + not tool_exists("gcc") + + shellescaped_dirname = Shellwords.escape(File.dirname(__FILE__)) + ljtname = File.join(File.dirname(__FILE__), "libjpeg-turbo-1.3.1") + shellescaped_ljtname = Shellwords.escape(ljtname) + + if File.exists?(File.join(ljtname, "djpeg")) then + $cjpeg = Shellwords.escape(File.join(ljtname, "cjpeg")) + $djpeg = Shellwords.escape(File.join(ljtname, "djpeg")) + return + end + + if not `md5sum #{shellescaped_ljtname}.tar.gz 2>&1` =~ /2c3a68129dac443a72815ff5bb374b05/ then + url = "http://downloads.sourceforge.net/project/libjpeg-turbo/1.3.1/libjpeg-turbo-1.3.1.tar.gz" + printf("Downloading libjpeg-turbo-1.3.1.tar.gz ...") + `wget -c #{url} -O #{shellescaped_ljtname}.tar.gz 2>&1` + if $?.to_i != 0 then + printf(" failed\n") + exit(1) + end + printf(" done\n") + end + if not `md5sum #{shellescaped_ljtname}.tar.gz 2>&1` =~ /2c3a68129dac443a72815ff5bb374b05/ then + printf("MD5 check failed for the downloaded libjpeg-turbo-1.3.1.tar.gz\n") + exit(1) + end + + printf("Extracting libjpeg-turbo-1.3.1.tar.gz ...") + `tar -xzf #{shellescaped_ljtname}.tar.gz -C #{shellescaped_dirname}` + if $?.to_i != 0 then + printf(" failed\n") + exit(1) + end + printf(" done\n") + + Dir.chdir(ljtname) { + printf("Compiling libjpeg-turbo, please be patient ...") + compilation_log = `./configure --disable-shared && make -j2 2>&1` + if $?.to_i != 0 then + printf(" failed\n%s\n", compilation_log) + exit(1) + end + printf(" done\n") + } + + $cjpeg = Shellwords.escape(File.join(ljtname, "cjpeg")) + $djpeg = Shellwords.escape(File.join(ljtname, "djpeg")) +end + +# Check if we have the right cjpeg and djpeg +if not `#{$djpeg} -v </dev/null 2>&1` =~ /libjpeg\-turbo/ or + not `#{$cjpeg} -v </dev/null 2>&1` =~ /libjpeg\-turbo/ +then + printf("The cjpeg and djpeg tools from libjpeg-turbo are not found.\n") + printf("Trying to download and compile them.\n") + download_and_compile_libjpeg_turbo() +end + +############################################################################### + +def create_random_jpg(filename, width, height) + IO.popen(sprintf("#{$cjpeg} -q 95 > %s", Shellwords.escape(filename)), "wb") {|fh| + fh.printf("P3\n%d %d\n255\n", width, height) + fh.write(Random.new(0).bytes(3 * width * height).bytes.to_a.map {|x| + x.to_s }.join(" ")) + } +end + +def read_file(filename) + return if not File.exists?(filename) + fh = File.open(filename, "rb") + data = fh.read + fh.close + return data +end + +def write_file(filename, data) + begin + fh = File.open(filename, "wb") + fh.write(data) + fh.close + rescue + return false + end + return true +end + +def set_userspace_governor(core) + write_file("/sys/devices/system/cpu/cpu#{core}/cpufreq/scaling_governor", "userspace") + governor = read_file("/sys/devices/system/cpu/cpu#{core}/cpufreq/scaling_governor") + return false if not governor + return governor.strip == "userspace" +end + +def set_freq(core, freq) + write_file("/sys/devices/system/cpu/cpu#{core}/cpufreq/scaling_setspeed", freq.to_s) + cur_freq = read_file("/sys/devices/system/cpu/cpu#{core}/cpufreq/scaling_cur_freq") + return false if not cur_freq + return cur_freq.to_i == freq +end + +def get_freq_list(core) + freq_list = read_file("/sys/devices/system/cpu/cpu#{core}/cpufreq/scaling_available_frequencies") + if not freq_list then + freq_list = read_file("/sys/devices/system/cpu/cpu#{core}/cpufreq/stats/time_in_state") + return [] if not freq_list + return freq_list.split(/\s+/).each_slice(2).map {|x| x[0].to_i} + end + return freq_list.split(" ").map {|x| x.to_i} +end + +jpgname = File.join(File.dirname(__FILE__), "whitenoise-1920x1080.jpg") +shellescaped_jpgname = Shellwords.escape(jpgname) + +if not File.exists?(jpgname) then + printf("Creating '%s' ...", jpgname) + create_random_jpg(jpgname, 1920, 1080) + printf(" done\n") +end + +number_of_cpu_cores = `nproc`.to_i + +test_failed = false + +min_freq = 0 +max_freq = 10000 + +printf("CPU stress test, which is doing JPEG decoding by libjpeg-turbo\n") +printf("at different cpufreq operating points.\n") + +if ARGV[0] and ARGV[1] then + min_freq = [ARGV[0].to_i, ARGV[1].to_i].min + max_freq = [ARGV[0].to_i, ARGV[1].to_i].max + printf("\nTesting CPU clock frequencies between %d MHz and %d MHz\n", + min_freq, max_freq) +end + +0.upto(number_of_cpu_cores - 1) {|core| + printf("\nTesting CPU %d\n", core) + if not set_userspace_governor(core) then + raise "Can't set the userspace cpufreq governor" + end + + freq_list = get_freq_list(core) + freq_list.sort.reverse.each {|freq| + printf("%5d MHz ", freq / 1000) + if freq < min_freq * 1000 or freq > max_freq * 1000 or not set_freq(core, freq) + then + printf("SKIPPED\n") + next + end + subtest_failed = false + expected_result = `taskset -c #{core} #{$djpeg} #{shellescaped_jpgname} | md5sum` + 1.upto(60) { + printf(".") + STDOUT.flush + if `taskset -c #{core} #{$djpeg} #{shellescaped_jpgname} | md5sum` != expected_result + then + subtest_failed = true + break + end + } + test_failed = true if subtest_failed + printf(subtest_failed ? " FAILED\n" : " OK\n") + } +} + +printf("\nOverall result : %s\n", (test_failed ? "FAILED" : "PASSED")) diff --git a/cpuburn/gnuplot-sunxi-cpufreq b/cpuburn/gnuplot-sunxi-cpufreq new file mode 100644 index 0000000..ba80b39 --- a/dev/null +++ b/cpuburn/gnuplot-sunxi-cpufreq @@ -0,0 +1,112 @@ +#!/usr/bin/env ruby +# +# Copyright © 2014 Siarhei Siamashka <siarhei.siamashka@gmail.com> +# +# 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 (including the next +# paragraph) 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 +# THE AUTHORS OR COPYRIGHT HOLDERS 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. + +require 'tempfile' + +# Test the availability of the required tools + +def tool_exists(tool_name) + `which #{tool_name} > /dev/null 2>&1` + if $?.to_i != 0 then + printf("Error: the required '%s' executable is not found in PATH\n", tool_name) + return false + else + return true + end +end + +exit(1) if not tool_exists("gnuplot") + +pngfile = nil +cpufreq_src_files = [] + +ARGV.each {|a| + if a =~ /\.png$/ then + pngfile = a + else + cpufreq_src_files.push(a) if File.exists?(a) + end +} + +if not pngfile or cpufreq_src_files.size == 0 then + printf("Usage: #{$PROGRAM_NAME} <png_file> <cpufreq_src_file> [cpufreq_src_file]\n") + printf("Where:\n") + printf(" png_file - resulting PNG file with the plot.\n") + printf(" cpufreq_src_file - source file with the cpufreq table\n") + printf(" to parse (from the sunxi-3.4 kernel).\n") + exit(1) +end + +data = {} +# Parse the linux-sunxi cpufreq tables +tablename = nil +cpufreq_src_files.each {|filename| + File.open(filename).each_line {|l| + if l =~ /static struct cpufreq_dvfs (.*?)[_]?dvfs_table\[\]/ then + tablename = $1 + tablename = "unknown" if tablename == "" + data[tablename] = [] if not data.has_key?(tablename) + end + if l =~ /\.freq\s*\=\s*(\d+),\s*\.volt\s*\=\s*(\d+)/ then + freq = $1.to_i / 1000000 + volt = $2.to_f / 1000 + if freq == 0 then + tablename = nil + end + data[tablename].push([freq, volt]) if tablename + end + } +} + +# Prepare and feed data to gnuplot +tmpfiles = {} +data.each {|tablename, data| + tmpfiles[tablename] = Tempfile.new(tablename) + data.each {|v| + tmpfiles[tablename].printf("%f %f\n", v[0], v[1]) + } + tmpfiles[tablename].flush +} + +IO.popen("gnuplot", "w") {|fh| + fh.write " + set terminal png size 1600, 900 + set output '#{pngfile}' + set format y '%.3f' + set xtics 48 + set ytics 0.025 + set grid xtics ytics + set yrange [0.9:1.575] + set xlabel 'CPU clock frequency, MHz' + set ylabel 'Required core voltage for reliable operation, V' + set style line 1 lc rgb 'blue' linewidth 10 + set style line 2 lc rgb 'cyan' linewidth 8 + set style line 3 lc rgb 'orange' linewidth 6 + set style line 4 lc rgb 'brown' linewidth 4 + " + plotdata = data.sort.map.with_index {|x, i| + "'%s' using 1:2 with linespoints ls #{i + 1} title '%s'" % + [tmpfiles[x[0]].path, x[0]] + } + fh.printf("plot %s\n", plotdata.join(",")) +} |