Re: [KERNEL]: Avoid divide in IS_ALIGN
"linux-os (Dick Johnson)" <[EMAIL PROTECTED]> writes: > Executing this script. > > cat #include > > #define IS_ALIGNED(x,a) (((x) % ((typeof(x))(a))) == 0) > #define _IS_ALIGNED(x, a) (((x) & ((typeof(x))(a) - 1)) == 0) > > int main() > { > int i; > long p = 0x12345678; > for(i=1; i< 0x11; i++) > printf("Old = %d, new = %d\n", IS_ALIGNED(p, i), _IS_ALIGNED(p, i)); Alignment is only defined for powers of two. Andreas. -- Andreas Schwab, SuSE Labs, [EMAIL PROTECTED] SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany PGP key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5 "And now for something completely different." - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [KERNEL]: Avoid divide in IS_ALIGN
On Tue, 20 Nov 2007, Richard B. Johnson wrote: > On Tue, 20 Nov 2007, Herbert Xu wrote: > >> Hi: >> >> [KERNEL]: Avoid divide in IS_ALIGN >> >> I was happy to discover the brand new IS_ALIGN macro and quickly >> used it in my code. To my dismay I found that the generated code >> used division to perform the test. >> >> This patch fixes it by changing the % test to an &. This avoids >> the division. >> >> Signed-off-by: Herbert Xu <[EMAIL PROTECTED]> >> >> Cheers, >> -- >> Visit Openswan at http://www.openswan.org/ >> Email: Herbert Xu ~{PmV>HI~} <[EMAIL PROTECTED]> >> Home Page: http://gondor.apana.org.au/~herbert/ >> PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt >> -- >> diff --git a/include/linux/kernel.h b/include/linux/kernel.h >> index 94bc996..39b3fa6 100644 >> --- a/include/linux/kernel.h >> +++ b/include/linux/kernel.h >> @@ -35,7 +35,7 @@ extern const char linux_proc_banner[]; >> #define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1) >> #define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask)) >> #define PTR_ALIGN(p, a) ((typeof(p))ALIGN((unsigned long)(p), >> (a))) >> -#define IS_ALIGNED(x,a) (((x) % ((typeof(x))(a))) == 0) >> +#define IS_ALIGNED(x, a)(((x) & ((typeof(x))(a) - 1)) == 0) >> > > Your macro modification is wrong. There was a brain fart on the explaination of why it's wrong. Here is a better explaination. Executing this script. cat </tmp/xxx.c #include #define IS_ALIGNED(x,a) (((x) % ((typeof(x))(a))) == 0) #define _IS_ALIGNED(x, a) (((x) & ((typeof(x))(a) - 1)) == 0) int main() { int i; long p = 0x12345678; for(i=1; i< 0x11; i++) printf("Old = %d, new = %d\n", IS_ALIGNED(p, i), _IS_ALIGNED(p, i)); return 0; } EOF gcc -Wall -o /tmp/xxx /tmp/xxx.c /tmp/xxx ... produces: Old = 1, new = 1 Old = 1, new = 1 Old = 1, new = 1 Old = 1, new = 1 Old = 0, new = 1 Old = 1, new = 1 Old = 0, new = 1 Old = 1, new = 1 Old = 1, new = 0 Old = 0, new = 0 Old = 0, new = 0 Old = 1, new = 0 Old = 0, new = 0 Old = 0, new = 0 Old = 0, new = 0 Old = 0, new = 0 Which is clearly different. Cheers, Dick Johnson Penguin : Linux version 2.6.22.1 on an i686 machine (5588.30 BogoMips). My book : http://www.AbominableFirebug.com/ _ The information transmitted in this message is confidential and may be privileged. Any review, retransmission, dissemination, or other use of this information by persons or entities other than the intended recipient is prohibited. If you are not the intended recipient, please notify Analogic Corporation immediately - by replying to this message or by sending an email to [EMAIL PROTECTED] - and destroy all copies of this information, including any attachments, without reading or disclosing them. Thank you. - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [KERNEL]: Avoid divide in IS_ALIGN
On Tue, 20 Nov 2007, Richard B. Johnson wrote: On Tue, 20 Nov 2007, Herbert Xu wrote: Hi: [KERNEL]: Avoid divide in IS_ALIGN I was happy to discover the brand new IS_ALIGN macro and quickly used it in my code. To my dismay I found that the generated code used division to perform the test. This patch fixes it by changing the % test to an . This avoids the division. Signed-off-by: Herbert Xu [EMAIL PROTECTED] Cheers, -- Visit Openswan at http://www.openswan.org/ Email: Herbert Xu ~{PmVHI~} [EMAIL PROTECTED] Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt -- diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 94bc996..39b3fa6 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -35,7 +35,7 @@ extern const char linux_proc_banner[]; #define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1) #define __ALIGN_MASK(x,mask) (((x)+(mask))~(mask)) #define PTR_ALIGN(p, a) ((typeof(p))ALIGN((unsigned long)(p), (a))) -#define IS_ALIGNED(x,a) (((x) % ((typeof(x))(a))) == 0) +#define IS_ALIGNED(x, a)(((x) ((typeof(x))(a) - 1)) == 0) Your macro modification is wrong. There was a brain fart on the explaination of why it's wrong. Here is a better explaination. Executing this script. cat EOF /tmp/xxx.c #include stdio.h #define IS_ALIGNED(x,a) (((x) % ((typeof(x))(a))) == 0) #define _IS_ALIGNED(x, a) (((x) ((typeof(x))(a) - 1)) == 0) int main() { int i; long p = 0x12345678; for(i=1; i 0x11; i++) printf(Old = %d, new = %d\n, IS_ALIGNED(p, i), _IS_ALIGNED(p, i)); return 0; } EOF gcc -Wall -o /tmp/xxx /tmp/xxx.c /tmp/xxx ... produces: Old = 1, new = 1 Old = 1, new = 1 Old = 1, new = 1 Old = 1, new = 1 Old = 0, new = 1 Old = 1, new = 1 Old = 0, new = 1 Old = 1, new = 1 Old = 1, new = 0 Old = 0, new = 0 Old = 0, new = 0 Old = 1, new = 0 Old = 0, new = 0 Old = 0, new = 0 Old = 0, new = 0 Old = 0, new = 0 Which is clearly different. Cheers, Dick Johnson Penguin : Linux version 2.6.22.1 on an i686 machine (5588.30 BogoMips). My book : http://www.AbominableFirebug.com/ _ The information transmitted in this message is confidential and may be privileged. Any review, retransmission, dissemination, or other use of this information by persons or entities other than the intended recipient is prohibited. If you are not the intended recipient, please notify Analogic Corporation immediately - by replying to this message or by sending an email to [EMAIL PROTECTED] - and destroy all copies of this information, including any attachments, without reading or disclosing them. Thank you. - To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [KERNEL]: Avoid divide in IS_ALIGN
linux-os (Dick Johnson) [EMAIL PROTECTED] writes: Executing this script. cat EOF /tmp/xxx.c #include stdio.h #define IS_ALIGNED(x,a) (((x) % ((typeof(x))(a))) == 0) #define _IS_ALIGNED(x, a) (((x) ((typeof(x))(a) - 1)) == 0) int main() { int i; long p = 0x12345678; for(i=1; i 0x11; i++) printf(Old = %d, new = %d\n, IS_ALIGNED(p, i), _IS_ALIGNED(p, i)); Alignment is only defined for powers of two. Andreas. -- Andreas Schwab, SuSE Labs, [EMAIL PROTECTED] SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany PGP key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5 And now for something completely different. - To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [KERNEL]: Avoid divide in IS_ALIGN
On Tue, 20 Nov 2007, Herbert Xu wrote: > Hi: > > [KERNEL]: Avoid divide in IS_ALIGN > > I was happy to discover the brand new IS_ALIGN macro and quickly > used it in my code. To my dismay I found that the generated code > used division to perform the test. > > This patch fixes it by changing the % test to an &. This avoids > the division. > > Signed-off-by: Herbert Xu <[EMAIL PROTECTED]> > > Cheers, > -- > Visit Openswan at http://www.openswan.org/ > Email: Herbert Xu ~{PmV>HI~} <[EMAIL PROTECTED]> > Home Page: http://gondor.apana.org.au/~herbert/ > PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt > -- > diff --git a/include/linux/kernel.h b/include/linux/kernel.h > index 94bc996..39b3fa6 100644 > --- a/include/linux/kernel.h > +++ b/include/linux/kernel.h > @@ -35,7 +35,7 @@ extern const char linux_proc_banner[]; > #define ALIGN(x,a)__ALIGN_MASK(x,(typeof(x))(a)-1) > #define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask)) > #define PTR_ALIGN(p, a) ((typeof(p))ALIGN((unsigned long)(p), > (a))) > -#define IS_ALIGNED(x,a) (((x) % ((typeof(x))(a))) == 0) > +#define IS_ALIGNED(x, a) (((x) & ((typeof(x))(a) - 1)) == 0) > Your macro modification is wrong. Take 0x12345600, which is aligned on a 16-byte boundary. Now, with your macro, we have for a 0x10 alignment: (0x12345600 & 0x0f) = (0x00 == 0) == TRUE (correct) For an 0x20 alignment: (0x12345600 & 0x1f) = (0x00 == 0) == TRUE (incorrect) In other words, the macro may work for some alignments, but not all. It is therefore wrong. You need the modulus, the remainder after division. Anything else is broken. Cheers, Dick Johnson Penguin : Linux version 2.6.22.1 on an i686 machine (5588.30 BogoMips). My book : http://www.AbominableFirebug.com/ _ The information transmitted in this message is confidential and may be privileged. Any review, retransmission, dissemination, or other use of this information by persons or entities other than the intended recipient is prohibited. If you are not the intended recipient, please notify Analogic Corporation immediately - by replying to this message or by sending an email to [EMAIL PROTECTED] - and destroy all copies of this information, including any attachments, without reading or disclosing them. Thank you. - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [KERNEL]: Avoid divide in IS_ALIGN
On Tue, 20 Nov 2007 10:17:15 -0800 Joe Perches <[EMAIL PROTECTED]> wrote: > On Tue, 2007-11-20 at 21:56 +0800, Herbert Xu wrote: > > [KERNEL]: Avoid divide in IS_ALIGN > > I was happy to discover the brand new IS_ALIGN macro and quickly > > used it in my code. To my dismay I found that the generated code > > used division to perform the test. > > This patch fixes it by changing the % test to an &. This avoids > > the division. > > Perhaps this should use is_power_of_2? > > #define IS_ALIGNED(x, a) \ > ({ typeof(x) _a = (typeof(x))(a); \ > is_power_of_2(_a) ? (((x) & (_a - 1)) == 0) \ >: (((x) % _a == 0); }) > > gcc -o2/oS seems to do the right thing. The other *ALIGN* macros in there are only good for power-of-2 alignments so I guess Herbert's change is OK. The whole thing's a bit crufty really - there's no reason why it _can't_ work on non-power-of-2 numbers 9via an implementation such as you suggest) and there's no commentary in there explaining that this will presently break things. Those macros are sufficiently obscure, risky and undocumented as to make them of dubious value IMO. I mean, anything which forces you to go and stare at the definition for a while when reviewing a callsite isn't worth it. - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [KERNEL]: Avoid divide in IS_ALIGN
On Tue, 2007-11-20 at 21:56 +0800, Herbert Xu wrote: > [KERNEL]: Avoid divide in IS_ALIGN > I was happy to discover the brand new IS_ALIGN macro and quickly > used it in my code. To my dismay I found that the generated code > used division to perform the test. > This patch fixes it by changing the % test to an &. This avoids > the division. Perhaps this should use is_power_of_2? #define IS_ALIGNED(x, a)\ ({ typeof(x) _a = (typeof(x))(a); \ is_power_of_2(_a) ? (((x) & (_a - 1)) == 0) \ : (((x) % _a == 0); }) gcc -o2/oS seems to do the right thing. - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[KERNEL]: Avoid divide in IS_ALIGN
Hi: [KERNEL]: Avoid divide in IS_ALIGN I was happy to discover the brand new IS_ALIGN macro and quickly used it in my code. To my dismay I found that the generated code used division to perform the test. This patch fixes it by changing the % test to an &. This avoids the division. Signed-off-by: Herbert Xu <[EMAIL PROTECTED]> Cheers, -- Visit Openswan at http://www.openswan.org/ Email: Herbert Xu ~{PmV>HI~} <[EMAIL PROTECTED]> Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt -- diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 94bc996..39b3fa6 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -35,7 +35,7 @@ extern const char linux_proc_banner[]; #define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1) #define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask)) #define PTR_ALIGN(p, a)((typeof(p))ALIGN((unsigned long)(p), (a))) -#define IS_ALIGNED(x,a)(((x) % ((typeof(x))(a))) == 0) +#define IS_ALIGNED(x, a) (((x) & ((typeof(x))(a) - 1)) == 0) #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr)) - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[KERNEL]: Avoid divide in IS_ALIGN
Hi: [KERNEL]: Avoid divide in IS_ALIGN I was happy to discover the brand new IS_ALIGN macro and quickly used it in my code. To my dismay I found that the generated code used division to perform the test. This patch fixes it by changing the % test to an . This avoids the division. Signed-off-by: Herbert Xu [EMAIL PROTECTED] Cheers, -- Visit Openswan at http://www.openswan.org/ Email: Herbert Xu ~{PmVHI~} [EMAIL PROTECTED] Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt -- diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 94bc996..39b3fa6 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -35,7 +35,7 @@ extern const char linux_proc_banner[]; #define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1) #define __ALIGN_MASK(x,mask) (((x)+(mask))~(mask)) #define PTR_ALIGN(p, a)((typeof(p))ALIGN((unsigned long)(p), (a))) -#define IS_ALIGNED(x,a)(((x) % ((typeof(x))(a))) == 0) +#define IS_ALIGNED(x, a) (((x) ((typeof(x))(a) - 1)) == 0) #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr)) - To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [KERNEL]: Avoid divide in IS_ALIGN
On Tue, 2007-11-20 at 21:56 +0800, Herbert Xu wrote: [KERNEL]: Avoid divide in IS_ALIGN I was happy to discover the brand new IS_ALIGN macro and quickly used it in my code. To my dismay I found that the generated code used division to perform the test. This patch fixes it by changing the % test to an . This avoids the division. Perhaps this should use is_power_of_2? #define IS_ALIGNED(x, a)\ ({ typeof(x) _a = (typeof(x))(a); \ is_power_of_2(_a) ? (((x) (_a - 1)) == 0) \ : (((x) % _a == 0); }) gcc -o2/oS seems to do the right thing. - To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [KERNEL]: Avoid divide in IS_ALIGN
On Tue, 20 Nov 2007 10:17:15 -0800 Joe Perches [EMAIL PROTECTED] wrote: On Tue, 2007-11-20 at 21:56 +0800, Herbert Xu wrote: [KERNEL]: Avoid divide in IS_ALIGN I was happy to discover the brand new IS_ALIGN macro and quickly used it in my code. To my dismay I found that the generated code used division to perform the test. This patch fixes it by changing the % test to an . This avoids the division. Perhaps this should use is_power_of_2? #define IS_ALIGNED(x, a) \ ({ typeof(x) _a = (typeof(x))(a); \ is_power_of_2(_a) ? (((x) (_a - 1)) == 0) \ : (((x) % _a == 0); }) gcc -o2/oS seems to do the right thing. The other *ALIGN* macros in there are only good for power-of-2 alignments so I guess Herbert's change is OK. The whole thing's a bit crufty really - there's no reason why it _can't_ work on non-power-of-2 numbers 9via an implementation such as you suggest) and there's no commentary in there explaining that this will presently break things. Those macros are sufficiently obscure, risky and undocumented as to make them of dubious value IMO. I mean, anything which forces you to go and stare at the definition for a while when reviewing a callsite isn't worth it. - To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [KERNEL]: Avoid divide in IS_ALIGN
On Tue, 20 Nov 2007, Herbert Xu wrote: Hi: [KERNEL]: Avoid divide in IS_ALIGN I was happy to discover the brand new IS_ALIGN macro and quickly used it in my code. To my dismay I found that the generated code used division to perform the test. This patch fixes it by changing the % test to an . This avoids the division. Signed-off-by: Herbert Xu [EMAIL PROTECTED] Cheers, -- Visit Openswan at http://www.openswan.org/ Email: Herbert Xu ~{PmVHI~} [EMAIL PROTECTED] Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt -- diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 94bc996..39b3fa6 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -35,7 +35,7 @@ extern const char linux_proc_banner[]; #define ALIGN(x,a)__ALIGN_MASK(x,(typeof(x))(a)-1) #define __ALIGN_MASK(x,mask) (((x)+(mask))~(mask)) #define PTR_ALIGN(p, a) ((typeof(p))ALIGN((unsigned long)(p), (a))) -#define IS_ALIGNED(x,a) (((x) % ((typeof(x))(a))) == 0) +#define IS_ALIGNED(x, a) (((x) ((typeof(x))(a) - 1)) == 0) Your macro modification is wrong. Take 0x12345600, which is aligned on a 16-byte boundary. Now, with your macro, we have for a 0x10 alignment: (0x12345600 0x0f) = (0x00 == 0) == TRUE (correct) For an 0x20 alignment: (0x12345600 0x1f) = (0x00 == 0) == TRUE (incorrect) In other words, the macro may work for some alignments, but not all. It is therefore wrong. You need the modulus, the remainder after division. Anything else is broken. Cheers, Dick Johnson Penguin : Linux version 2.6.22.1 on an i686 machine (5588.30 BogoMips). My book : http://www.AbominableFirebug.com/ _ The information transmitted in this message is confidential and may be privileged. Any review, retransmission, dissemination, or other use of this information by persons or entities other than the intended recipient is prohibited. If you are not the intended recipient, please notify Analogic Corporation immediately - by replying to this message or by sending an email to [EMAIL PROTECTED] - and destroy all copies of this information, including any attachments, without reading or disclosing them. Thank you. - To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/