From patchwork Fri Mar 20 22:25:44 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tobias Jakobi X-Patchwork-Id: 6061351 Return-Path: X-Original-To: patchwork-linux-samsung-soc@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 28F349F2A9 for ; Fri, 20 Mar 2015 22:26:04 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id CB39F204E3 for ; Fri, 20 Mar 2015 22:26:02 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 9563A204D5 for ; Fri, 20 Mar 2015 22:26:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751415AbbCTW0B (ORCPT ); Fri, 20 Mar 2015 18:26:01 -0400 Received: from smtp.math.uni-bielefeld.de ([129.70.45.10]:53617 "EHLO smtp.math.uni-bielefeld.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751174AbbCTW0A (ORCPT ); Fri, 20 Mar 2015 18:26:00 -0400 Received: from chidori.lan (unknown [5.147.63.78]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (Client did not present a certificate) by smtp.math.uni-bielefeld.de (Postfix) with ESMTPSA id 8D94460FAA; Fri, 20 Mar 2015 23:25:58 +0100 (CET) From: Tobias Jakobi To: linux-samsung-soc@vger.kernel.org Cc: dri-devel@lists.freedesktop.org, emil.l.velikov@gmail.com, jy0922.shim@samsung.com, m.szyprowski@samsung.com, inki.dae@samsung.com, Tobias Jakobi Subject: [PATCH 1/5] tests/exynos: add fimg2d performance analysis Date: Fri, 20 Mar 2015 23:25:44 +0100 Message-Id: <1426890348-12807-2-git-send-email-tjakobi@math.uni-bielefeld.de> X-Mailer: git-send-email 2.0.5 In-Reply-To: <1426890348-12807-1-git-send-email-tjakobi@math.uni-bielefeld.de> References: <1426890348-12807-1-git-send-email-tjakobi@math.uni-bielefeld.de> Sender: linux-samsung-soc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-samsung-soc@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Currently only fast solid color clear performance is measured. A large buffer is allocated and solid color clear operations are executed on it with randomly chosen properties (position and size of the region, clear color). Execution time is measured and output together with the amount of pixels processed. The 'simple' variant only executes one G2D command buffer at a time, while the 'multi' variant executes multiple ones. This can be used to measure setup/exec overhead. The test also serves a stability check. If clocks/voltages are too high or low respectively, the test quickly reveals this. Signed-off-by: Tobias Jakobi --- tests/exynos/Makefile.am | 8 +- tests/exynos/exynos_fimg2d_perf.c | 245 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 252 insertions(+), 1 deletion(-) create mode 100644 tests/exynos/exynos_fimg2d_perf.c diff --git a/tests/exynos/Makefile.am b/tests/exynos/Makefile.am index b21d016..243f957 100644 --- a/tests/exynos/Makefile.am +++ b/tests/exynos/Makefile.am @@ -5,9 +5,11 @@ AM_CFLAGS = \ -I $(top_srcdir)/exynos \ -I $(top_srcdir) +bin_PROGRAMS = exynos_fimg2d_perf + if HAVE_LIBKMS if HAVE_INSTALL_TESTS -bin_PROGRAMS = \ +bin_PROGRAMS += \ exynos_fimg2d_test else noinst_PROGRAMS = \ @@ -15,6 +17,10 @@ noinst_PROGRAMS = \ endif endif +exynos_fimg2d_perf_LDADD = \ + $(top_builddir)/libdrm.la \ + $(top_builddir)/exynos/libdrm_exynos.la + exynos_fimg2d_test_LDADD = \ $(top_builddir)/libdrm.la \ $(top_builddir)/libkms/libkms.la \ diff --git a/tests/exynos/exynos_fimg2d_perf.c b/tests/exynos/exynos_fimg2d_perf.c new file mode 100644 index 0000000..f45cacc --- /dev/null +++ b/tests/exynos/exynos_fimg2d_perf.c @@ -0,0 +1,245 @@ +#include +#include +#include + +#include + +#include "exynos_drm.h" +#include "exynos_drmif.h" +#include "exynos_fimg2d.h" + +/* Enable to format the output so that it can be fed into Mathematica. */ +#define OUTPUT_MATHEMATICA 0 + +static int fimg2d_perf_simple(struct exynos_bo *bo, struct g2d_context *ctx, + unsigned buf_width, unsigned buf_height, unsigned iterations) +{ + struct timespec tspec = { 0 }; + struct g2d_image img = { 0 }; + + unsigned long long g2d_time; + unsigned i; + int ret = 0; + + img.width = buf_width; + img.height = buf_height; + img.stride = buf_width * 4; + img.color_mode = G2D_COLOR_FMT_ARGB8888 | G2D_ORDER_AXRGB; + img.buf_type = G2D_IMGBUF_GEM; + img.bo[0] = bo->handle; + + srand(time(NULL)); + + printf("starting simple G2D performance test\n"); + printf("buffer width = %u, buffer height = %u, iterations = %u\n", + buf_width, buf_height, iterations); + +#if (OUTPUT_MATHEMATICA == 1) + putchar('{'); +#endif + + for (i = 0; i < iterations; ++i) { + unsigned x, y, w, h; + + x = rand() % buf_width; + y = rand() % buf_height; + + if (x == (buf_width - 1)) + x -= 1; + if (y == (buf_height - 1)) + y -= 1; + + w = rand() % (buf_width - x); + h = rand() % (buf_height - y); + + if (w == 0) w = 1; + if (h == 0) h = 1; + + img.color = rand(); + + ret = g2d_solid_fill(ctx, &img, x, y, w, h); + + clock_gettime(CLOCK_MONOTONIC, &tspec); + + if (ret == 0) + ret = g2d_exec(ctx); + + if (ret != 0) { + fprintf(stderr, "error: iteration %u failed (x = %u, y = %u, w = %u, h = %u)\n", + i, x, y, w, h); + break; + } else { + struct timespec end = { 0 }; + clock_gettime(CLOCK_MONOTONIC, &end); + + g2d_time = (end.tv_sec - tspec.tv_sec) * 1000000000ULL; + g2d_time += (end.tv_nsec - tspec.tv_nsec); + +#if (OUTPUT_MATHEMATICA == 1) + if (i != 0) putchar(','); + printf("{%u,%llu}", w * h, g2d_time); +#else + printf("num_pixels = %u, usecs = %llu\n", w * h, g2d_time); +#endif + } + } + +#if (OUTPUT_MATHEMATICA == 1) + printf("}\n"); +#endif + + return ret; +} + +static int fimg2d_perf_multi(struct exynos_bo *bo, struct g2d_context *ctx, + unsigned buf_width, unsigned buf_height, unsigned iterations, unsigned batch) +{ + struct timespec tspec = { 0 }; + struct g2d_image *images; + + unsigned long long g2d_time; + unsigned i, j; + int ret = 0; + + images = calloc(batch, sizeof(struct g2d_image)); + for (i = 0; i < batch; ++i) { + images[i].width = buf_width; + images[i].height = buf_height; + images[i].stride = buf_width * 4; + images[i].color_mode = G2D_COLOR_FMT_ARGB8888 | G2D_ORDER_AXRGB; + images[i].buf_type = G2D_IMGBUF_GEM; + images[i].bo[0] = bo->handle; + } + + srand(time(NULL)); + + printf("starting multi G2D performance test (batch size = %u)\n", batch); + printf("buffer width = %u, buffer height = %u, iterations = %u\n", + buf_width, buf_height, iterations); + +#if (OUTPUT_MATHEMATICA == 1) + putchar('{'); +#endif + + for (i = 0; i < iterations; ++i) { + unsigned num_pixels = 0; + + for (j = 0; j < batch; ++j) { + unsigned x, y, w, h; + + x = rand() % buf_width; + y = rand() % buf_height; + + if (x == (buf_width - 1)) + x -= 1; + if (y == (buf_height - 1)) + y -= 1; + + w = rand() % (buf_width - x); + h = rand() % (buf_height - y); + + if (w == 0) w = 1; + if (h == 0) h = 1; + + images[j].color = rand(); + + num_pixels += w * h; + + ret = g2d_solid_fill(ctx, &images[j], x, y, w, h); + if (ret != 0) + break; + } + + clock_gettime(CLOCK_MONOTONIC, &tspec); + + if (ret == 0) + ret = g2d_exec(ctx); + + if (ret != 0) { + fprintf(stderr, "error: iteration %u failed (num_pixels = %u)\n", i, num_pixels); + break; + break; + } else { + struct timespec end = { 0 }; + clock_gettime(CLOCK_MONOTONIC, &end); + + g2d_time = (end.tv_sec - tspec.tv_sec) * 1000000000ULL; + g2d_time += (end.tv_nsec - tspec.tv_nsec); + +#if (OUTPUT_MATHEMATICA == 1) + if (i != 0) putchar(','); + printf("{%u,%llu}", num_pixels, g2d_time); +#else + printf("num_pixels = %u, usecs = %llu\n", num_pixels, g2d_time); +#endif + } + } + +#if (OUTPUT_MATHEMATICA == 1) + printf("}\n"); +#endif + + return ret; +} + +int main(int argc, char **argv) +{ + int fd, ret; + + struct exynos_device *dev; + struct g2d_context *ctx; + struct exynos_bo *bo; + + ret = 0; + + fd = drmOpen("exynos", NULL); + if (fd < 0) { + fprintf(stderr, "error: failed to open drm\n"); + ret = -1; + + goto out; + } + + dev = exynos_device_create(fd); + if (dev == NULL) { + fprintf(stderr, "error: failed to create device\n"); + ret = -2; + + goto fail; + } + + ctx = g2d_init(fd); + if (ctx == NULL) { + fprintf(stderr, "error: failed to init G2D\n"); + ret = -3; + + goto g2d_fail; + } + + bo = exynos_bo_create(dev, 4096 * 4096 * 4, 0); + if (bo == NULL) { + fprintf(stderr, "error: failed to create bo\n"); + ret = -4; + + goto bo_fail; + } + + ret = fimg2d_perf_simple(bo, ctx, 4096, 4096, 128); + + if (ret == 0) + ret = fimg2d_perf_multi(bo, ctx, 4096, 4096, 128, 3); + + exynos_bo_destroy(bo); + +bo_fail: + g2d_fini(ctx); + +g2d_fail: + exynos_device_destroy(dev); + +fail: + drmClose(fd); + +out: + return ret; +}