wpwrak | wolfspraul: downloads.qi-hardware.com has amnesia again :( (volume not mounted) | 00:02 |
---|---|---|
wpwrak | heh. i have root there ! fixed ;-) | 00:04 |
-:#qi-hardware- [freenode-info] why register and identify? your IRC nick is how people know you. http://freenode.net/faq.shtml#nicksetup | 06:33 | |
DocScrutinizer05 | haha :-) | 07:22 |
larsc | two functions in the kernel, round_down() and rounddown() both behave differently... | 07:26 |
kyak | different results or different algorithms? | 07:31 |
kyak | if the results are different, i would argue that one of these functions is incorrect :) | 07:31 |
larsc | one of them only works correctly when the divisor is a power of two | 07:33 |
larsc | but now try to rememeber which is which | 07:33 |
larsc | and then there is also ALIGN() | 07:33 |
larsc | which does the same, but also only works with a power of two | 07:33 |
kyak | talking about quality in linux kernel.. | 07:35 |
larsc | I've given up on that long time ago ;) | 07:36 |
larsc | the 'good' news is the BSDs which pride themselves in quality are usually worse | 07:36 |
larsc | yea, now that I'm using the right function my driver works again | 07:38 |
kyak | i suppose that they may pay more attention to quality, but then they just have fewer eyes to look at their code.. So despite that there is no "real" quality control in linux development, there are more eyes (like yours) that catch things that don't suppose to happen | 07:39 |
kyak | are you going to bug report this? :) | 07:39 |
larsc | fixing this will take some time, but a quick grep revealed that there are other places that use round_down with non-power-of-twos | 07:41 |
kyak | ..and probably rely on incorrect behaviour | 07:44 |
larsc | sometimes the incorrect behaviour just goes unoticed. e.g. in my case the divisor could be 4 or 3, if it was 4 everything works fine | 07:51 |
DocScrutinizer05 | ((<larsc> yea, now that I'm using the right function my driver works again)) hehe :-) | 07:53 |
eintopf | guys, read this http://lists.infradead.org/pipermail/barebox/2014-July/020065.html | 07:54 |
eintopf | round_up/round_down are optimized to (and only work with) | 07:54 |
eintopf | power-of-2 arguments. | 07:54 |
DocScrutinizer05 | yep, that's what I'd expect, hearing the story above | 07:55 |
kyak | oh, so it's "documented"! | 07:55 |
kyak | very well :) | 07:56 |
eintopf | note: that's not the linux kernel :-) | 07:56 |
DocScrutinizer05 | and a general rule: never replace a function in a lib or kernel, particularly not with a "bugfixed" version. Somebody might rely and depend on that particular bug | 07:56 |
larsc | kyak: It is documented for barebox | 07:57 |
larsc | not in the kernel | 07:57 |
eintopf | in the kernel also | 07:58 |
eintopf | include/linux/kernel.h | 07:58 |
eintopf | https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/include/linux/kernel.h?id=refs/tags/v3.16-rc5#n56 | 07:59 |
eintopf | barebox adapt kernel driver interface, so it's mostly copy&paste do add a new driver to the bootloader | 08:00 |
eintopf | but barebox has no irq framework :/ | 08:00 |
kyak | the implementation of round_* is interesting. How does it work? | 08:01 |
eintopf | power-of to are always 1 and followed by many zeros | 08:01 |
eintopf | so you get a mask if you substract one | 08:02 |
eintopf | and then do a little bit magic :/ | 08:02 |
kyak | let me think about it :) | 08:03 |
eintopf | I mean, all 4 divided numbers are 0xXXXXX4 | 08:03 |
eintopf | and all 0x400 divided numbers are 0xXXXX400 | 08:03 |
eintopf | and all POWER_OF_TWO divided numbers are 0xXXXXPOWER_OF_TWO | 08:03 |
eintopf | something like that | 08:04 |
Action: eintopf can't explain it | 08:04 | |
larsc | kyak: round_down() basically set the ilog2(n) lower bits in the word to zero | 08:04 |
larsc | round_up() sets them to one and then adds one | 08:04 |
larsc | round_up is a bit ineffcient though, it uses 3 arithmetic instructions while it can be done in two | 08:06 |
eintopf | larsc: send-patches | 08:06 |
larsc | maybe | 08:06 |
kyak | ok, i take 2^3 = 8 (1000) for example as y. Then y-1 is 0111. ~(y-1) is 1000 (that is, y) - so what's the point? | 08:07 |
larsc | kyak: it is ...111111111000 | 08:08 |
kyak | ah.. you are ight.. because it is casted to type of x? | 08:08 |
eintopf | ~ is xor | 08:09 |
larsc | no | 08:09 |
larsc | it's not | 08:09 |
larsc | it's 'not' | 08:09 |
larsc | kyak: ~ inverts all bits in the word | 08:10 |
eintopf | yes :-) | 08:10 |
whitequark | that's not xor | 08:10 |
eintopf | yes :( | 08:10 |
eintopf | I mean it's like setting register bits reg &= ~(foo) | 08:11 |
kyak | yep, so the word is type of x in this case, not type of y, therefore we get extra "ones" | 08:11 |
eintopf | ehm, clearing register bits | 08:11 |
larsc | kyak: by default in C the type of 8 is int | 08:12 |
larsc | so ~(8-1) != 8, even without a typecast | 08:13 |
kyak | right, but what about uint4_t a=8; ~(a-1) ? :) | 08:14 |
DocScrutinizer05 | 4= 0x100, next larger power of 2 is 8= 0x1000. So all < 8 = 5,6, 7 become 4 on round down. 0x101, 0x110 and 0x111 -> 0x100 | 08:14 |
kyak | i have a feeling there should be an easier way to zero down the set amount of lower bits... | 08:15 |
DocScrutinizer05 | 8 = 0x1000 -1= 0x111, mask lower 1s: 0x100; 0x100 & 0x1xx -> 0x100 | 08:15 |
DocScrutinizer05 | some CPUs even have an opcode for this | 08:17 |
kyak | for rounding down to nearest power of two? | 08:18 |
kyak | wait, that raises a question | 08:18 |
kyak | why would anyone require the second argument, y? | 08:19 |
larsc | it's not the nearest power of two | 08:19 |
kyak | what is the use case of rounding down to an arbitraty powwer of two? | 08:19 |
larsc | it's the power of two you specify for y | 08:19 |
kyak | could it be that the sole reason of argument y is because it is used in calculations? | 08:20 |
larsc | e.g. if you hardware is only able to process objects which size is a multiple of a certain power of two | 08:21 |
DocScrutinizer05 | err sorry. I actually don't get it what "round down X to 2^n" is useful for. Isn't the result always 2^n unless X < 2^n? | 08:24 |
kyak | ok, i see. But if you round down "further away" than the nearest power of two, you are loosing to much information. It would mean that your implementation is probably wronf | 08:24 |
kyak | you might as well just always output that required power of two and not calculate anything :) | 08:25 |
DocScrutinizer05 | my point | 08:25 |
DocScrutinizer05 | unless X < 2^n# | 08:26 |
DocScrutinizer05 | -# | 08:26 |
kyak | my guess is that the 'y' is an argument because it is used to calculate the mask | 08:26 |
DocScrutinizer05 | so round_down is actually a range limiting aka clipping function | 08:27 |
kyak | and than my another point that there should be an easier implemention of round_down | 08:27 |
kyak | without requiring y and round to nearest power of two | 08:27 |
DocScrutinizer05 | for a 16bit argument X make sure it's 0< X<2^n | 08:27 |
kyak | yep | 08:28 |
kyak | it should be called range_lim | 08:28 |
kyak | or whatever | 08:28 |
DocScrutinizer05 | with n anything between 15 and 1 | 08:28 |
DocScrutinizer05 | err 15 and 0 actually | 08:29 |
DocScrutinizer05 | kyak: exactly | 08:29 |
DocScrutinizer05 | for a round_down I'd expect 5->4 and 3->2 | 08:30 |
kyak | really the question is whether this behaviour is intended by round_down() authors or it is just an effect of their implementation | 08:30 |
DocScrutinizer05 | actually 7,6,5->4 | 08:31 |
DocScrutinizer05 | clipping functions are widely used, and as I said are available as opcode in several ISA | 08:32 |
eintopf | :o | 08:32 |
DocScrutinizer05 | can't recall the usual name of c/whatever high level language of that function | 08:33 |
DocScrutinizer05 | it's prolly not max() | 08:33 |
DocScrutinizer05 | language name of that function. Pardon my french | 08:35 |
kyak | i wonder how round_down() would behave if we supply y > x... | 08:35 |
larsc | returns 0 | 08:35 |
larsc | as it should | 08:35 |
Action: eintopf used round_down() in some kernel code | 08:36 | |
kyak | anyway, i conclude that this function is weird :) | 08:36 |
kyak | eintopf: do you use it to round down to nearest power of two or to arbitraty power of two? | 08:36 |
DocScrutinizer05 | I guess usually the compiler converts that functio (let's call it max(x, y) ) into code rather than a function call | 08:36 |
kyak | and the question is - how do you know what's that 'nearest' in advance? | 08:37 |
DocScrutinizer05 | but actually I wonder how compiler would know that y is always a power of 2 so it can create optinized code | 08:38 |
eintopf | I use it for the nearest | 08:38 |
kyak | to use this function, the developer must know in advance the value he wants to round down to.. that's weird | 08:38 |
eintopf | some RFC payload attributes use the nearest divide by 8 | 08:38 |
DocScrutinizer05 | kyak: the value you want to round down to is your upper limit of range | 08:39 |
larsc | kyak: round_down() returns the nearest value that is smaller or equal to x and is also a multiple of y | 08:39 |
DocScrutinizer05 | e.g. clip values calculated in a 32bit register to 16bit | 08:40 |
DocScrutinizer05 | or 15 bit when the target is a signed int16 | 08:40 |
larsc | DocScrutinizer05: that would be clamp() | 08:40 |
DocScrutinizer05 | sounds good | 08:41 |
DocScrutinizer05 | aiui round_down is doing exactly that | 08:41 |
kyak | ok, it's more clear now | 08:41 |
DocScrutinizer05 | actually a clamp diode does exactly that for a voltage on an input pin :-) | 08:42 |
larsc | DocScrutinizer05: round_down() does something else | 08:43 |
DocScrutinizer05 | then I didn't get the explanation what round_down is doing | 08:43 |
larsc | round_down(x, y) return a value z for which x >= z > x-y and z is a multiple of y | 08:44 |
DocScrutinizer05 | ooh | 08:44 |
DocScrutinizer05 | thanks! | 08:44 |
larsc | round_up(x, y) return a value z for which x <= z < x+y and z is a multiple of y | 08:45 |
DocScrutinizer05 | that makes sense | 08:46 |
DocScrutinizer05 | though for y=2^n... | 08:47 |
DocScrutinizer05 | I can't find a non-negative value x for arbitrary y=2^n where round_down(x, 2^n) is _not_ identical to clip(x, 2^n) | 08:51 |
DocScrutinizer05 | maybe lack of coffee | 08:52 |
eintopf | send patches, somebody of the global review will scream if it's not identical | 08:53 |
DocScrutinizer05 | err clamp | 08:53 |
eintopf | :-) | 08:53 |
larsc | DocScrutinizer05: x=5 y=2 | 08:53 |
larsc | round_down(5, 2) = 4 | 08:54 |
larsc | clamp(5,2) = 2 | 08:54 |
DocScrutinizer05 | lack of coffee, evidently | 08:54 |
DocScrutinizer05 | thanks, and sorry for the noise | 08:54 |
DocScrutinizer05 | ok, to correct myself: I never seen round_down() in any ISA | 08:58 |
larsc | if y is a constant the compiler will internally compute ~(y - 1) so the whole operation boils down to a simple and | 08:59 |
DocScrutinizer05 | :nod: | 09:00 |
Action: DocScrutinizer05 ponders more coffee | 09:00 | |
DocScrutinizer05 | maybe I'm simply over the top with coffee, and rather need a walk and sth to eat | 09:01 |
kyak | round_down(56,8) is 56 | 09:49 |
kyak | now i'm confused again | 09:49 |
kyak | ah, because 56 is multiple of 8 | 09:50 |
kyak | or, in other words, 56 already has it's 3 lower bits cleared | 09:53 |
kyak | larsc: what's your use case for this function? | 09:53 |
larsc | only reading whole data sets from a sample fifo | 09:56 |
larsc | in the fifo I have X,Y and Z data | 09:56 |
larsc | and I want to make sure that I only read complete sets of data | 09:56 |
larsc | so I read the number of samples in the fifo and then rounddown() to the nearest multiple of 3 | 09:57 |
kyak | i see, so you only grab XYZ, XYZ, XYZ. But what happens to the remaining X or XY, if they are in fifo? | 09:58 |
kyak | i mean, do you discard those samples by rounding? | 09:58 |
kyak | linux.h is a treasury of things like that :) | 10:06 |
kyak | why the hell they need a do-while loop in swap()? | 10:06 |
eintopf | maybe because to turn off compiler optimization | 10:07 |
eintopf | if it's a do { } while (0); | 10:07 |
kyak | yes , so the while loop basically doesn't exist | 10:08 |
kyak | what would compiler try to optimize here and what would be the consequences of this optimization? | 10:09 |
eintopf | it's not optimization | 10:09 |
eintopf | it's more turn off compiler weird things :-) | 10:09 |
eintopf | I don't know it exactly | 10:10 |
kyak | i can only hope that they know :) | 10:10 |
eintopf | maybe generate assembler code | 10:10 |
eintopf | with and without | 10:10 |
eintopf | then you know more | 10:10 |
kyak | there are separate macros for max and max3 (for three arguments), and same for min/min3. Wouldn't it be possible to create a universal macro for any number of arguments? | 10:10 |
kyak | eintopf: or maybe just a line of comment in source code would help. Maybe this is some stupid workaround for gcc v 1.0 | 10:11 |
eintopf | i am not a compiler expert, sry | 10:11 |
kyak | 99.99% of people aren't. So leave a sensible comment, god damn them | 10:12 |
eintopf | comment is the code :-) | 10:12 |
eintopf | :X | 10:12 |
kyak | min_not_zero - return the minimum that is _not_ zero, unless both are zero | 10:13 |
kyak | oh, common! | 10:13 |
kyak | are they going to come up with a separate function for every unpossible use case? | 10:13 |
kyak | like the family of clamp_* functions | 10:13 |
kyak | actually, i have troubles understanding this phrase even in human language "minimum that is _not_ zero, unless both are zero" | 10:14 |
kyak | this requires some thinking :) | 10:14 |
kyak | and i imaging one day i would require such function, and then i would have no fucking clue that such exists in priceless linux.h | 10:15 |
larsc | it is acutally a quite useful function which helps to eliminate a lot of boilderplate code | 10:24 |
larsc | it is not that rare that for settings where 0 does not make sense it is regarded as infinity | 10:25 |
kyak | but this function can still return 0, despite of it's name | 10:27 |
kyak | and despite that you treat 0 as infinity | 10:28 |
larsc | only if both a and b is 0 | 10:28 |
kyak | yes, sure | 10:28 |
larsc | which is correct | 10:28 |
larsc | min_zero_is_infitiy() is a guly name ;) | 10:28 |
larsc | min_but_zero_counts_as_infinity() | 10:28 |
kyak | anyway, i'm just too far away from this.. if you say it's useful, i trust you :) | 10:28 |
kyak | min_not_zero_except_both_zeros() | 10:30 |
kyak | --) | 10:30 |
kyak | larsc: so what happens to data in fifo that didn't fit into your multiple of three series? | 10:32 |
kyak | also, would it be possible to just read() from fifo in series of three? | 10:33 |
ysionneau | 12:06 < kyak> why the hell they need a do-while loop in swap()? < http://kernelnewbies.org/FAQ/DoWhile0 | 10:37 |
kyak | ysionneau: oh, thanks@ | 10:40 |
larsc | kyak: the data stays in the fifo until a full set is available | 10:41 |
kyak | larsc: but if you've already read the data from fifo (including the incomplete set), how do you put it back in fifo? | 10:45 |
larsc | I read the number of samples from the hardware | 10:45 |
larsc | then round that down to the nearest multiple of three | 10:45 |
larsc | and read that many samples from the fifo | 10:45 |
kyak | ok, i got it | 10:45 |
DocScrutinizer05 | ((<kyak> i mean, do you discard those samples by rounding?)) those stay in FIFO for next time | 10:51 |
kyak | yep, that's clear now | 10:51 |
DocScrutinizer05 | oops, seen larsc answered it a few lines up | 10:54 |
kyak | he did :) | 10:54 |
DocScrutinizer05 | a FIFO usually implemented as ring buffer, with a pointer to data start and one to data end | 10:55 |
DocScrutinizer05 | you fill the FIFO by incrementing pointer to end, and after reading n from pointer to start, you increment the pointer to start accordingly | 10:56 |
DocScrutinizer05 | hw does same | 11:00 |
--- Fri Jul 18 2014 | 00:00 |
Generated by irclog2html.py 2.9.2 by Marius Gedminas - find it at mg.pov.lt!