[Intel-gfx] [PATCH igt] igt/gem_fence_thresh: Use streaming reads for verify
Chris Wilson
chris at chris-wilson.co.uk
Fri Oct 6 20:53:48 UTC 2017
Quoting Chris Wilson (2017-08-23 13:55:55)
> At the moment, the verify tests use an extremely brutal write-read of
> every dword, degrading performance to UC. If we break those up into
> cachelines, we can do a wcb write/read at a time instead, roughly 8x
> faster. We lose the accuracy of the forced wcb flushes around every dword,
> but we are retaining the overall behaviour of checking reads following
> writes instead. To compensate, we do check that a single dword write/read
> before using wcb aligned accesses.
This fixes one of the APL timeouts...
> Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
> ---
> tests/gem_fence_thrash.c | 116 +++++++++++++++++++++++++++++++++++++++++------
> 1 file changed, 101 insertions(+), 15 deletions(-)
>
> diff --git a/tests/gem_fence_thrash.c b/tests/gem_fence_thrash.c
> index 52095f26..3e1edb73 100644
> --- a/tests/gem_fence_thrash.c
> +++ b/tests/gem_fence_thrash.c
> @@ -30,7 +30,6 @@
> #include "config.h"
> #endif
>
> -#include "igt.h"
> #include <unistd.h>
> #include <stdlib.h>
> #include <stdio.h>
> @@ -43,6 +42,12 @@
> #include <pthread.h>
> #include "drm.h"
>
> +#include "igt.h"
> +#include "igt_x86.h"
> +
> +#define PAGE_SIZE 4096
> +#define CACHELINE 64
> +
> #define OBJECT_SIZE (128*1024) /* restricted to 1MiB alignment on i915 fences */
>
> /* Before introduction of the LRU list for fences, allocation of a fence for a page
> @@ -104,15 +109,78 @@ bo_copy (void *_arg)
> return NULL;
> }
>
> +#if defined(__x86_64__) && !defined(__clang__)
> +#define MOVNT 512
> +
> +#pragma GCC push_options
> +#pragma GCC target("sse4.1")
> +
> +#include <smmintrin.h>
> +__attribute__((noinline))
> +static void copy_wc_page(void *dst, void *src)
> +{
> + if (igt_x86_features() & SSE4_1) {
> + __m128i *S = (__m128i *)src;
> + __m128i *D = (__m128i *)dst;
> +
> + for (int i = 0; i < PAGE_SIZE/CACHELINE; i++) {
> + __m128i tmp[4];
> +
> + tmp[0] = _mm_stream_load_si128(S++);
> + tmp[1] = _mm_stream_load_si128(S++);
> + tmp[2] = _mm_stream_load_si128(S++);
> + tmp[3] = _mm_stream_load_si128(S++);
> +
> + _mm_store_si128(D++, tmp[0]);
> + _mm_store_si128(D++, tmp[1]);
> + _mm_store_si128(D++, tmp[2]);
> + _mm_store_si128(D++, tmp[3]);
> + }
> + } else
> + memcpy(dst, src, PAGE_SIZE);
> +}
> +static void copy_wc_cacheline(void *dst, void *src)
> +{
> + if (igt_x86_features() & SSE4_1) {
> + __m128i *S = (__m128i *)src;
> + __m128i *D = (__m128i *)dst;
> + __m128i tmp[4];
> +
> + tmp[0] = _mm_stream_load_si128(S++);
> + tmp[1] = _mm_stream_load_si128(S++);
> + tmp[2] = _mm_stream_load_si128(S++);
> + tmp[3] = _mm_stream_load_si128(S++);
> +
> + _mm_store_si128(D++, tmp[0]);
> + _mm_store_si128(D++, tmp[1]);
> + _mm_store_si128(D++, tmp[2]);
> + _mm_store_si128(D++, tmp[3]);
> + } else
> + memcpy(dst, src, CACHELINE);
> +}
> +
> +#pragma GCC pop_options
> +
> +#else
> +static void copy_wc_page(void *dst, const void *src)
> +{
> + memcpy(dst, src, PAGE_SIZE);
> +}
> +static void copy_wc_cacheline(void *dst, const void *src)
> +{
> + memcpy(dst, src, CACHELINE);
> +}
> +#endif
> +
> static void
> _bo_write_verify(struct test *t)
> {
> int fd = t->fd;
> int i, k;
> uint32_t **s;
> - uint32_t v;
> unsigned int dwords = OBJECT_SIZE >> 2;
> const char *tile_str[] = { "none", "x", "y" };
> + uint32_t tmp[PAGE_SIZE/sizeof(uint32_t)];
>
> igt_assert(t->tiling >= 0 && t->tiling <= I915_TILING_Y);
> igt_assert_lt(0, t->num_surfaces);
> @@ -124,21 +192,39 @@ _bo_write_verify(struct test *t)
> s[k] = bo_create(fd, t->tiling);
>
> for (k = 0; k < t->num_surfaces; k++) {
> - volatile uint32_t *a = s[k];
> -
> - for (i = 0; i < dwords; i++) {
> - a[i] = i;
> - v = a[i];
> - igt_assert_f(v == i,
> - "tiling %s: write failed at %d (%x)\n",
> - tile_str[t->tiling], i, v);
> + uint32_t *a = s[k];
> +
> + a[0] = 0xdeadbeef;
> + igt_assert_f(a[0] == 0xdeadbeef,
> + "tiling %s: write failed at start (%x)\n",
> + tile_str[t->tiling], a[0]);
> +
> + a[dwords - 1] = 0xc0ffee;
> + igt_assert_f(a[dwords - 1] == 0xc0ffee,
> + "tiling %s: write failed at end (%x)\n",
> + tile_str[t->tiling], a[dwords - 1]);
> +
> + for (i = 0; i < dwords; i += CACHELINE/sizeof(uint32_t)) {
> + for (int j = 0; j < CACHELINE/sizeof(uint32_t); j++)
> + a[i + j] = ~(i + j);
> +
> + copy_wc_cacheline(tmp, a + i);
> + for (int j = 0; j < CACHELINE/sizeof(uint32_t); j++)
> + igt_assert_f(tmp[j] == ~(i+ j),
> + "tiling %s: write failed at %d (%x)\n",
> + tile_str[t->tiling], i + j, tmp[j]);
> +
> + for (int j = 0; j < CACHELINE/sizeof(uint32_t); j++)
> + a[i + j] = i + j;
> }
>
> - for (i = 0; i < dwords; i++) {
> - v = a[i];
> - igt_assert_f(v == i,
> - "tiling %s: verify failed at %d (%x)\n",
> - tile_str[t->tiling], i, v);
> + for (i = 0; i < dwords; i += PAGE_SIZE/sizeof(uint32_t)) {
> + copy_wc_page(tmp, a + i);
> + for (int j = 0; j < PAGE_SIZE/sizeof(uint32_t); j++) {
> + igt_assert_f(tmp[j] == i + j,
> + "tiling %s: verify failed at %d (%x)\n",
> + tile_str[t->tiling], i + j, tmp[j]);
> + }
> }
> }
>
> --
> 2.14.1
>
More information about the Intel-gfx
mailing list