You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Graham Leggett <mi...@sharp.fm> on 2013/04/29 18:03:41 UTC

Potential optimisation - move flags to the start of the struct

Hi all,

A number of the modules have flags, and with additions typically over time the flags end up looking like this, which takes up a lot of space:

struct {
	[variable]
	[flag]
	[variable]
	[flag]
	…
}

Would it make sense to group the flags at the beginning, in theory allowing us to add flags without breaking the ABI?

struct {
	[flag:1]
	[flag:1}
	… (within reason, 32 flags max?)
	[variable]
	[variable]
	…
}

Is it safe to practically assume that the bit field will be at least 32 bits wide, or are there cases were we might see a 16 bit word?

Something like this:

Index: modules/proxy/mod_proxy.h
===================================================================
--- modules/proxy/mod_proxy.h	(revision 1476661)
+++ modules/proxy/mod_proxy.h	(working copy)
@@ -128,6 +128,22 @@
 };
 
 typedef struct {
+    unsigned int req_set:1;
+    unsigned int viaopt_set:1;
+    unsigned int recv_buffer_size_set:1;
+    unsigned int io_buffer_size_set:1;
+    unsigned int maxfwd_set:1;
+    unsigned int timeout_set:1;
+    unsigned int badopt_set:1;
+    unsigned int proxy_status_set:1;
+    unsigned int source_address_set:1;
+    unsigned int bgrowth_set:1;
+    unsigned int bal_persist:1;
+    unsigned int inherit:1;
+    unsigned int inherit_set:1;
+    unsigned int ppinherit:1;
+    unsigned int ppinherit_set:1;
+
     apr_array_header_t *proxies;
     apr_array_header_t *sec_proxy;
     apr_array_header_t *aliases;
@@ -168,25 +184,25 @@
     ap_slotmem_instance_t *bslot;  /* balancers shm data - runtime */
     ap_slotmem_provider_t *storage;
 
-    unsigned int req_set:1;
-    unsigned int viaopt_set:1;
-    unsigned int recv_buffer_size_set:1;
-    unsigned int io_buffer_size_set:1;
-    unsigned int maxfwd_set:1;
-    unsigned int timeout_set:1;
-    unsigned int badopt_set:1;
-    unsigned int proxy_status_set:1;
-    unsigned int source_address_set:1;
-    unsigned int bgrowth_set:1;
-    unsigned int bal_persist:1;
-    unsigned int inherit:1;
-    unsigned int inherit_set:1;
-    unsigned int ppinherit:1;
-    unsigned int ppinherit_set:1;
 } proxy_server_conf;
 
 
 typedef struct {
+    /**
+     * the following setting masks the error page
+     * returned from the 'proxied server' and just
+     * forwards the status code upwards.
+     * This allows the main server (us) to generate
+     * the error page, (so it will look like a error
+     * returned from the rest of the system
+     */
+    unsigned int error_override:1;
+    unsigned int preserve_host:1;
+    unsigned int preserve_host_set:1;
+    unsigned int error_override_set:1;
+    unsigned int alias_set:1;
+    unsigned int add_forwarded_headers:1;
+
     const char *p;            /* The path */
     ap_regex_t  *r;            /* Is this a regex? */
 
@@ -205,20 +221,6 @@
     signed char interpolate_env;
     struct proxy_alias *alias;
 
-    /**
-     * the following setting masks the error page
-     * returned from the 'proxied server' and just
-     * forwards the status code upwards.
-     * This allows the main server (us) to generate
-     * the error page, (so it will look like a error
-     * returned from the rest of the system
-     */
-    unsigned int error_override:1;
-    unsigned int preserve_host:1;
-    unsigned int preserve_host_set:1;
-    unsigned int error_override_set:1;
-    unsigned int alias_set:1;
-    unsigned int add_forwarded_headers:1;
 } proxy_dir_conf;
 
 /* if we interpolate env vars per-request, we'll need a per-request

Regards,
Graham
--


Re: Potential optimisation - move flags to the start of the struct

Posted by Jim Jagielski <ji...@jaguNET.com>.
Of course, we could also just have

	unsigned int flags1  /* 32 flags */
	unsigned int flags2  /* and 32 more, just in case */
	

and use bit ops.

Not as "clear" but allows for expansion :)

On Apr 29, 2013, at 1:58 PM, Jim Jagielski <ji...@jaguNET.com> wrote:

> IIRC, bit fields are normally int-word sized.
> 
> On Apr 29, 2013, at 12:03 PM, Graham Leggett <mi...@sharp.fm> wrote:
> 
>> Hi all,
>> 
>> A number of the modules have flags, and with additions typically over time the flags end up looking like this, which takes up a lot of space:
>> 
>> struct {
>> 	[variable]
>> 	[flag]
>> 	[variable]
>> 	[flag]
>> 	…
>> }
>> 
>> Would it make sense to group the flags at the beginning, in theory allowing us to add flags without breaking the ABI?
>> 
>> struct {
>> 	[flag:1]
>> 	[flag:1}
>> 	… (within reason, 32 flags max?)
>> 	[variable]
>> 	[variable]
>> 	…
>> }
>> 
>> Is it safe to practically assume that the bit field will be at least 32 bits wide, or are there cases were we might see a 16 bit word?
>> 
>> Something like this:
>> 
>> Index: modules/proxy/mod_proxy.h
>> ===================================================================
>> --- modules/proxy/mod_proxy.h	(revision 1476661)
>> +++ modules/proxy/mod_proxy.h	(working copy)
>> @@ -128,6 +128,22 @@
>> };
>> 
>> typedef struct {
>> +    unsigned int req_set:1;
>> +    unsigned int viaopt_set:1;
>> +    unsigned int recv_buffer_size_set:1;
>> +    unsigned int io_buffer_size_set:1;
>> +    unsigned int maxfwd_set:1;
>> +    unsigned int timeout_set:1;
>> +    unsigned int badopt_set:1;
>> +    unsigned int proxy_status_set:1;
>> +    unsigned int source_address_set:1;
>> +    unsigned int bgrowth_set:1;
>> +    unsigned int bal_persist:1;
>> +    unsigned int inherit:1;
>> +    unsigned int inherit_set:1;
>> +    unsigned int ppinherit:1;
>> +    unsigned int ppinherit_set:1;
>> +
>>    apr_array_header_t *proxies;
>>    apr_array_header_t *sec_proxy;
>>    apr_array_header_t *aliases;
>> @@ -168,25 +184,25 @@
>>    ap_slotmem_instance_t *bslot;  /* balancers shm data - runtime */
>>    ap_slotmem_provider_t *storage;
>> 
>> -    unsigned int req_set:1;
>> -    unsigned int viaopt_set:1;
>> -    unsigned int recv_buffer_size_set:1;
>> -    unsigned int io_buffer_size_set:1;
>> -    unsigned int maxfwd_set:1;
>> -    unsigned int timeout_set:1;
>> -    unsigned int badopt_set:1;
>> -    unsigned int proxy_status_set:1;
>> -    unsigned int source_address_set:1;
>> -    unsigned int bgrowth_set:1;
>> -    unsigned int bal_persist:1;
>> -    unsigned int inherit:1;
>> -    unsigned int inherit_set:1;
>> -    unsigned int ppinherit:1;
>> -    unsigned int ppinherit_set:1;
>> } proxy_server_conf;
>> 
>> 
>> typedef struct {
>> +    /**
>> +     * the following setting masks the error page
>> +     * returned from the 'proxied server' and just
>> +     * forwards the status code upwards.
>> +     * This allows the main server (us) to generate
>> +     * the error page, (so it will look like a error
>> +     * returned from the rest of the system
>> +     */
>> +    unsigned int error_override:1;
>> +    unsigned int preserve_host:1;
>> +    unsigned int preserve_host_set:1;
>> +    unsigned int error_override_set:1;
>> +    unsigned int alias_set:1;
>> +    unsigned int add_forwarded_headers:1;
>> +
>>    const char *p;            /* The path */
>>    ap_regex_t  *r;            /* Is this a regex? */
>> 
>> @@ -205,20 +221,6 @@
>>    signed char interpolate_env;
>>    struct proxy_alias *alias;
>> 
>> -    /**
>> -     * the following setting masks the error page
>> -     * returned from the 'proxied server' and just
>> -     * forwards the status code upwards.
>> -     * This allows the main server (us) to generate
>> -     * the error page, (so it will look like a error
>> -     * returned from the rest of the system
>> -     */
>> -    unsigned int error_override:1;
>> -    unsigned int preserve_host:1;
>> -    unsigned int preserve_host_set:1;
>> -    unsigned int error_override_set:1;
>> -    unsigned int alias_set:1;
>> -    unsigned int add_forwarded_headers:1;
>> } proxy_dir_conf;
>> 
>> /* if we interpolate env vars per-request, we'll need a per-request
>> 
>> Regards,
>> Graham
>> --
>> 
> 


Re: Potential optimisation - move flags to the start of the struct

Posted by Jim Jagielski <ji...@jaguNET.com>.
IIRC, bit fields are normally int-word sized.

On Apr 29, 2013, at 12:03 PM, Graham Leggett <mi...@sharp.fm> wrote:

> Hi all,
> 
> A number of the modules have flags, and with additions typically over time the flags end up looking like this, which takes up a lot of space:
> 
> struct {
> 	[variable]
> 	[flag]
> 	[variable]
> 	[flag]
> 	…
> }
> 
> Would it make sense to group the flags at the beginning, in theory allowing us to add flags without breaking the ABI?
> 
> struct {
> 	[flag:1]
> 	[flag:1}
> 	… (within reason, 32 flags max?)
> 	[variable]
> 	[variable]
> 	…
> }
> 
> Is it safe to practically assume that the bit field will be at least 32 bits wide, or are there cases were we might see a 16 bit word?
> 
> Something like this:
> 
> Index: modules/proxy/mod_proxy.h
> ===================================================================
> --- modules/proxy/mod_proxy.h	(revision 1476661)
> +++ modules/proxy/mod_proxy.h	(working copy)
> @@ -128,6 +128,22 @@
> };
> 
> typedef struct {
> +    unsigned int req_set:1;
> +    unsigned int viaopt_set:1;
> +    unsigned int recv_buffer_size_set:1;
> +    unsigned int io_buffer_size_set:1;
> +    unsigned int maxfwd_set:1;
> +    unsigned int timeout_set:1;
> +    unsigned int badopt_set:1;
> +    unsigned int proxy_status_set:1;
> +    unsigned int source_address_set:1;
> +    unsigned int bgrowth_set:1;
> +    unsigned int bal_persist:1;
> +    unsigned int inherit:1;
> +    unsigned int inherit_set:1;
> +    unsigned int ppinherit:1;
> +    unsigned int ppinherit_set:1;
> +
>     apr_array_header_t *proxies;
>     apr_array_header_t *sec_proxy;
>     apr_array_header_t *aliases;
> @@ -168,25 +184,25 @@
>     ap_slotmem_instance_t *bslot;  /* balancers shm data - runtime */
>     ap_slotmem_provider_t *storage;
> 
> -    unsigned int req_set:1;
> -    unsigned int viaopt_set:1;
> -    unsigned int recv_buffer_size_set:1;
> -    unsigned int io_buffer_size_set:1;
> -    unsigned int maxfwd_set:1;
> -    unsigned int timeout_set:1;
> -    unsigned int badopt_set:1;
> -    unsigned int proxy_status_set:1;
> -    unsigned int source_address_set:1;
> -    unsigned int bgrowth_set:1;
> -    unsigned int bal_persist:1;
> -    unsigned int inherit:1;
> -    unsigned int inherit_set:1;
> -    unsigned int ppinherit:1;
> -    unsigned int ppinherit_set:1;
> } proxy_server_conf;
> 
> 
> typedef struct {
> +    /**
> +     * the following setting masks the error page
> +     * returned from the 'proxied server' and just
> +     * forwards the status code upwards.
> +     * This allows the main server (us) to generate
> +     * the error page, (so it will look like a error
> +     * returned from the rest of the system
> +     */
> +    unsigned int error_override:1;
> +    unsigned int preserve_host:1;
> +    unsigned int preserve_host_set:1;
> +    unsigned int error_override_set:1;
> +    unsigned int alias_set:1;
> +    unsigned int add_forwarded_headers:1;
> +
>     const char *p;            /* The path */
>     ap_regex_t  *r;            /* Is this a regex? */
> 
> @@ -205,20 +221,6 @@
>     signed char interpolate_env;
>     struct proxy_alias *alias;
> 
> -    /**
> -     * the following setting masks the error page
> -     * returned from the 'proxied server' and just
> -     * forwards the status code upwards.
> -     * This allows the main server (us) to generate
> -     * the error page, (so it will look like a error
> -     * returned from the rest of the system
> -     */
> -    unsigned int error_override:1;
> -    unsigned int preserve_host:1;
> -    unsigned int preserve_host_set:1;
> -    unsigned int error_override_set:1;
> -    unsigned int alias_set:1;
> -    unsigned int add_forwarded_headers:1;
> } proxy_dir_conf;
> 
> /* if we interpolate env vars per-request, we'll need a per-request
> 
> Regards,
> Graham
> --
>