From patchwork Sat Jun 5 00:16:23 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Anholt X-Patchwork-Id: 104355 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by demeter.kernel.org (8.14.3/8.14.3) with ESMTP id o550GYxE018971 for ; Sat, 5 Jun 2010 00:17:10 GMT Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 5BC5E9EF9D for ; Fri, 4 Jun 2010 17:16:34 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from annarchy.freedesktop.org (annarchy.freedesktop.org [131.252.210.176]) by gabe.freedesktop.org (Postfix) with ESMTP id C492F9E75C; Fri, 4 Jun 2010 17:16:25 -0700 (PDT) Received: from pollan.anholt.net (annarchy.freedesktop.org [127.0.0.1]) by annarchy.freedesktop.org (Postfix) with ESMTP id 843801300C2; Fri, 4 Jun 2010 17:16:25 -0700 (PDT) Received: by pollan.anholt.net (Postfix, from userid 1000) id 4D09C32C059; Fri, 4 Jun 2010 17:16:24 -0700 (PDT) From: Eric Anholt To: intel-gfx@lists.freedesktop.org Date: Fri, 4 Jun 2010 17:16:23 -0700 Message-Id: <1275696983-15198-1-git-send-email-eric@anholt.net> X-Mailer: git-send-email 1.7.1 Subject: [Intel-gfx] [PATCH] intel: Add more intermediate sizes of cache buckets between powers of 2. X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org Errors-To: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Sat, 05 Jun 2010 00:17:10 +0000 (UTC) diff --git a/intel/intel_bufmgr_gem.c b/intel/intel_bufmgr_gem.c index b76fd7e..c3e189e 100644 --- a/intel/intel_bufmgr_gem.c +++ b/intel/intel_bufmgr_gem.c @@ -66,6 +66,8 @@ fprintf(stderr, __VA_ARGS__); \ } while (0) +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + typedef struct _drm_intel_bo_gem drm_intel_bo_gem; struct drm_intel_gem_bo_bucket { @@ -73,10 +75,6 @@ struct drm_intel_gem_bo_bucket { unsigned long size; }; -/* Only cache objects up to 64MB. Bigger than that, and the rounding of the - * size makes many operations fail that wouldn't otherwise. - */ -#define DRM_INTEL_GEM_BO_BUCKETS 14 typedef struct _drm_intel_bufmgr_gem { drm_intel_bufmgr bufmgr; @@ -93,7 +91,8 @@ typedef struct _drm_intel_bufmgr_gem { int exec_count; /** Array of lists of cached gem objects of power-of-two sizes */ - struct drm_intel_gem_bo_bucket cache_bucket[DRM_INTEL_GEM_BO_BUCKETS]; + struct drm_intel_gem_bo_bucket cache_bucket[14 * 4]; + int num_buckets; uint64_t gtt_size; int available_fences; @@ -285,7 +284,7 @@ drm_intel_gem_bo_bucket_for_size(drm_intel_bufmgr_gem *bufmgr_gem, { int i; - for (i = 0; i < DRM_INTEL_GEM_BO_BUCKETS; i++) { + for (i = 0; i < bufmgr_gem->num_buckets; i++) { struct drm_intel_gem_bo_bucket *bucket = &bufmgr_gem->cache_bucket[i]; if (bucket->size >= size) { @@ -822,7 +821,7 @@ drm_intel_gem_cleanup_bo_cache(drm_intel_bufmgr_gem *bufmgr_gem, time_t time) { int i; - for (i = 0; i < DRM_INTEL_GEM_BO_BUCKETS; i++) { + for (i = 0; i < bufmgr_gem->num_buckets; i++) { struct drm_intel_gem_bo_bucket *bucket = &bufmgr_gem->cache_bucket[i]; @@ -1250,7 +1249,7 @@ drm_intel_bufmgr_gem_destroy(drm_intel_bufmgr *bufmgr) pthread_mutex_destroy(&bufmgr_gem->lock); /* Free any cached buffer objects we were going to reuse */ - for (i = 0; i < DRM_INTEL_GEM_BO_BUCKETS; i++) { + for (i = 0; i < bufmgr_gem->num_buckets; i++) { struct drm_intel_gem_bo_bucket *bucket = &bufmgr_gem->cache_bucket[i]; drm_intel_bo_gem *bo_gem; @@ -1960,6 +1959,46 @@ drm_intel_gem_bo_references(drm_intel_bo *bo, drm_intel_bo *target_bo) return 0; } +static void +add_bucket(drm_intel_bufmgr_gem *bufmgr_gem, int size) +{ + unsigned int i = bufmgr_gem->num_buckets; + + assert(i < ARRAY_SIZE(bufmgr_gem->cache_bucket)); + + DRMINITLISTHEAD(&bufmgr_gem->cache_bucket[i].head); + bufmgr_gem->cache_bucket[i].size = size; + bufmgr_gem->num_buckets++; +} + +static void +init_cache_buckets(drm_intel_bufmgr_gem *bufmgr_gem) +{ + unsigned long size, cache_max_size = 64 * 1024 * 1024; + + /* Initialize the linked lists for BO reuse cache. */ + for (size = 4096; size <= cache_max_size; size *= 2) { + add_bucket(bufmgr_gem, size); + + /* OK, so power of two buckets was too wasteful of + * memory. Give 3 other sizes between each power of + * two, to hopefully cover things accurately enough. + * (The alternative is probably to just go for exact + * matching of sizes, and assume that for things like + * composited window resize the tiled width/height + * alignment and rounding of sizes to pages will get + * us useful cache hit rates anyway) + */ + if (size == 8192) { + add_bucket(bufmgr_gem, size + size / 2); + } else if (size < cache_max_size) { + add_bucket(bufmgr_gem, size + size * 1 / 4); + add_bucket(bufmgr_gem, size + size * 2 / 4); + add_bucket(bufmgr_gem, size + size * 3 / 4); + } + } +} + /** * Initializes the GEM buffer manager, which uses the kernel to allocate, map, * and manage map buffer objections. @@ -1972,8 +2011,7 @@ drm_intel_bufmgr_gem_init(int fd, int batch_size) drm_intel_bufmgr_gem *bufmgr_gem; struct drm_i915_gem_get_aperture aperture; drm_i915_getparam_t gp; - int ret, i; - unsigned long size; + int ret; int exec2 = 0; bufmgr_gem = calloc(1, sizeof(*bufmgr_gem)); @@ -2092,11 +2130,7 @@ drm_intel_bufmgr_gem_init(int fd, int batch_size) drm_intel_gem_get_pipe_from_crtc_id; bufmgr_gem->bufmgr.bo_references = drm_intel_gem_bo_references; - /* Initialize the linked lists for BO reuse cache. */ - for (i = 0, size = 4096; i < DRM_INTEL_GEM_BO_BUCKETS; i++, size *= 2) { - DRMINITLISTHEAD(&bufmgr_gem->cache_bucket[i].head); - bufmgr_gem->cache_bucket[i].size = size; - } + init_cache_buckets(bufmgr_gem); return &bufmgr_gem->bufmgr; }