blob: eeb7f9beb80e3d2541c09579225f641324b91a2b [file] [log] [blame]
/*
* Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.cts.dram;
import android.content.Context;
import android.graphics.Point;
import android.util.Log;
import android.view.WindowManager;
import com.android.cts.util.ResultType;
import com.android.cts.util.ResultUnit;
import android.cts.util.CtsAndroidTestCase;
import com.android.cts.util.ReportLog;
import com.android.cts.util.Stat;
/**
* check how many screens the memcpy function can copy in a sec.
* Note that this does not represent the total memory bandwidth available in the system
* as typically CPU cannot use the whole bandwidth.
* Smaller buffers can fit into L1 or L2 cache, which can show big boost.
*/
public class BandwidthTest extends CtsAndroidTestCase {
private static final String TAG = BandwidthTest.class.getSimpleName();
private static final int MEMCPY_REPETITION = 10;
private static final int MEMSET_REPETITION = 30;
private static final int REPEAT_IN_EACH_CALL = 100;
private static final int KB = 1024;
private static final int MB = 1024 * 1024;
private static final int MEMSET_CHAR = 0xa5;
// reject data outside +/- this value * median
private static final double OUTLIER_THRESHOLD = 0.1;
@Override
protected void setUp() throws Exception {
super.setUp();
// warm-up
MemoryNative.runMemcpy(2 * MB, 100);
}
public void testMemcpyK004() {
doRunMemcpy(4 * KB);
}
public void testMemcpyK008() {
doRunMemcpy(8 * KB);
}
public void testMemcpyK016() {
doRunMemcpy(16 * KB);
}
public void testMemcpyK032() {
doRunMemcpy(32 * KB);
}
public void testMemcpyK064() {
doRunMemcpy(64 * KB);
}
public void testMemcpyK128() {
doRunMemcpy(128 * KB);
}
public void testMemcpyK256() {
doRunMemcpy(256 * KB);
}
public void testMemcpyK512() {
doRunMemcpy(512 * KB);
}
public void testMemcpyM001() {
doRunMemcpy(1 * MB);
}
public void testMemcpyM002() {
doRunMemcpy(2 * MB);
}
public void testMemcpyM004() {
doRunMemcpy(4 * MB);
}
public void testMemcpyM008() {
doRunMemcpy(8 * MB);
}
public void testMemcpyM016() {
doRunMemcpy(16 * MB);
}
public void testMemsetK004() {
doRunMemset(4 * KB);
}
public void testMemsetK008() {
doRunMemset(8 * KB);
}
public void testMemsetK016() {
doRunMemset(16 * KB);
}
public void testMemsetK032() {
doRunMemset(32 * KB);
}
public void testMemsetK064() {
doRunMemset(64 * KB);
}
public void testMemsetK128() {
doRunMemset(128 * KB);
}
public void testMemsetK256() {
doRunMemset(256 * KB);
}
public void testMemsetK512() {
doRunMemset(512 * KB);
}
public void testMemsetM001() {
doRunMemset(1 * MB);
}
public void testMemsetM002() {
doRunMemset(2 * MB);
}
public void testMemsetM004() {
doRunMemset(4 * MB);
}
public void testMemsetM008() {
doRunMemset(8 * MB);
}
public void testMemsetM016() {
doRunMemset(16 * MB);
}
private void doRunMemcpy(int bufferSize) {
double[] result = new double[MEMCPY_REPETITION];
int repeatInEachCall = REPEAT_IN_EACH_CALL;
if (bufferSize < (1 * MB)) {
// too small buffer size finishes too early to give accurate result.
repeatInEachCall *= (1 * MB / bufferSize);
}
for (int i = 0; i < MEMCPY_REPETITION; i++) {
result[i] = MemoryNative.runMemcpy(bufferSize, repeatInEachCall);
}
getReportLog().printArray("memcpy time", result, ResultType.LOWER_BETTER,
ResultUnit.MS);
double[] mbps = ReportLog.calcRatePerSecArray(
(double)bufferSize * repeatInEachCall / 1024.0 / 1024.0, result);
getReportLog().printArray("memcpy throughput", mbps, ResultType.HIGHER_BETTER,
ResultUnit.MBPS);
Stat.StatResult stat = Stat.getStatWithOutlierRejection(mbps, OUTLIER_THRESHOLD);
if (stat.mDataCount != result.length) {
Log.w(TAG, "rejecting " + (result.length - stat.mDataCount) + " outliers");
}
WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
Point size = new Point();
wm.getDefaultDisplay().getSize(size);
Log.i(TAG, " x " + size.x + " y " + size.y);
double pixels = size.x * size.y;
// now this represents how many times the whole screen can be copied in a sec.
double screensPerSecAverage = stat.mAverage / pixels * 1024.0 * 1024.0 / 4.0;
getReportLog().printValue("memcpy in fps", screensPerSecAverage,
ResultType.HIGHER_BETTER, ResultUnit.FPS);
getReportLog().printSummary("memcpy throughput", stat.mAverage, ResultType.HIGHER_BETTER,
ResultUnit.MBPS);
}
private void doRunMemset(int bufferSize) {
double[] result = new double[MEMSET_REPETITION];
int repeatInEachCall = REPEAT_IN_EACH_CALL;
if (bufferSize < (1 * MB)) {
// too small buffer size finishes too early to give accurate result.
repeatInEachCall *= (1 * MB / bufferSize);
}
for (int i = 0; i < MEMSET_REPETITION; i++) {
result[i] = MemoryNative.runMemset(bufferSize, repeatInEachCall, MEMSET_CHAR);
}
getReportLog().printArray("memset time", result, ResultType.LOWER_BETTER,
ResultUnit.MS);
double[] mbps = ReportLog.calcRatePerSecArray(
(double)bufferSize * repeatInEachCall / 1024.0 / 1024.0, result);
getReportLog().printArray("memset throughput", mbps, ResultType.HIGHER_BETTER,
ResultUnit.MBPS);
Stat.StatResult stat = Stat.getStatWithOutlierRejection(mbps, OUTLIER_THRESHOLD);
if (stat.mDataCount != result.length) {
Log.w(TAG, "rejecting " + (result.length - stat.mDataCount) + " outliers");
}
WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
Point size = new Point();
wm.getDefaultDisplay().getSize(size);
Log.i(TAG, " x " + size.x + " y " + size.y);
double pixels = size.x * size.y;
// now this represents how many times the whole screen can be copied in a sec.
double screensPerSecAverage = stat.mAverage / pixels * 1024.0 * 1024.0 / 4.0;
getReportLog().printValue("memset in fps", screensPerSecAverage,
ResultType.HIGHER_BETTER, ResultUnit.FPS);
getReportLog().printSummary("memset throughput", stat.mAverage, ResultType.HIGHER_BETTER,
ResultUnit.MBPS);
}
}