Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Locked thread
spankmeister
Jun 15, 2008






It depends on the processor architecture what a bitwise shift actually does. So maybe that? Idk.

Adbot
ADBOT LOVES YOU

Malcolm XML
Aug 8, 2009

I always knew it would end like this.
What's the best way to capture and demodulate a 433.92 bfsk transmission

spankmeister
Jun 15, 2008






Gnuradio

It's free software

Malcolm XML
Aug 8, 2009

I always knew it would end like this.

spankmeister posted:

Gnuradio

It's free software

Im on windows and it doesn't want to recognize my rtl sdr

Spatial
Nov 15, 2007

Sagebrush posted:

got what i imagine is a real simple question:

assuming that the goal is to chop a large piece of data into individual bytes, is there a functional difference between

byte b = (32_bit_int >> 24);

and

byte b = (32_bit_int >> 24) & 0xFF;

?

I've seen both the bit-shifting alone and the shift-and-mask method and I dunno what is the difference.
there's no difference, either way the result is truncated. they will probably even compile to the same thing.

on ARM you can even do this in one instruction:
uxtb r0, r1, ror #24

Sweevo
Nov 8, 2007

i sometimes throw cables away

i mean straight into the bin without spending 10+ years in the box of might-come-in-handy-someday first

im a fucking monster

Sagebrush posted:

got what i imagine is a real simple question:

assuming that the goal is to chop a large piece of data into individual bytes, is there a functional difference between

byte b = (32_bit_int >> 24);

and

byte b = (32_bit_int >> 24) & 0xFF;

?

I've seen both the bit-shifting alone and the shift-and-mask method and I dunno what is the difference.

if it compiles to a logical shift instruction then both are the same since logical shifting right puts zeros in at the left-hand side, so there's no need to zero them out later. whereas if it compiles to an arithmetic shift instruction then the left bits will be copies of the MSB of the input value (this preserves the sign in the result), so the leftmost bits might not be zero. it depends on the architecture/compiler, and whether or not the input value is declared as signed or unsigned. if you want it to be portable then shift+mask is more likely to be correct across different systems, but shifting alone is probably correct in 95% of cases.

spankmeister
Jun 15, 2008






Malcolm XML posted:

Im on windows and it doesn't want to recognize my rtl sdr

run linux in a vm and hook up the usb to the vm


srsly it works a lot better that way

spankmeister
Jun 15, 2008






Sweevo posted:

if it compiles to a logical shift instruction then both are the same since logical shifting right puts zeros in at the left-hand side, so there's no need to zero them out later. whereas if it compiles to an arithmetic shift instruction then the left bits will be copies of the MSB of the input value (this preserves the sign in the result), so the leftmost bits might not be zero. it depends on the architecture/compiler, and whether or not the input value is declared as signed or unsigned. if you want it to be portable then shift+mask is more likely to be correct across different systems, but shifting alone is probably correct in 95% of cases.

Thank you this is what I was getting at but couldn't explain.

Spatial
Nov 15, 2007

don't use signed types for bit twiddling or you will suffer greatly

tbh logical shift and arithmetic shift should have been separate operators. 99% of the time you don't want the behaviour to differ based on signedness

gonadic io
Feb 16, 2011

>>=
what use case does logical shift have except trying to out-optimise the compiler when multiplying/dividing by powers of 2?

Spatial
Nov 15, 2007

a thread about janitoring individual bits - what use case does logical shift have

hobbesmaster
Jan 28, 2008

Spatial posted:

a thread about janitoring individual bits - what use case does logical shift have

what use case does it have in a high level programming language

if you're writing asm and dealing with signed numbers maybe? I'm not sure I've ever written anything where it'd be relevant

gonadic io
Feb 16, 2011

>>=
Wait poo poo I got them the wrong way around. I'm all for bitshifting, I guess I meant arithmetic shift

Sweevo
Nov 8, 2007

i sometimes throw cables away

i mean straight into the bin without spending 10+ years in the box of might-come-in-handy-someday first

im a fucking monster

gonadic io posted:

what use case does logical shift have except trying to out-optimise the compiler when multiplying/dividing by powers of 2?

they both have their uses. the difference is down to what happens to the MSB during right shifts.



if you're using it for division then arithmetic shift gives the wrong result for unsigned values that have the MSB set, whereas logical shift gives the wrong result for negative values. which one to use depends on whether the input is signed or not, and whether you're using the shift to divide by 2, or to actually move the bits around for some low-level reason like dealing with hardware registers.

the divide by 2 thing was a big deal before processors had divide instructions, or where the divide instruction was very slow.

for left shifts both logical and arithmetic shifts do the same thing and just shift the bits one place left. this works correctly regardless of the sign of the input, so logical and arithmetic left shifts are compiled to the same instruction.

Sweevo fucked around with this message at 16:24 on Jul 21, 2017

Spatial
Nov 15, 2007

oh. well arithmetic shifts aren't that common. i've only used them for two reasons: fixed point arithmetic scaling while preserving signedness and for dynamically generating bitfield masks. this is part of why i suggested splitting arithmetic/logic shifts into separate operators, because sign extension is usually not what you want.

Sweevo
Nov 8, 2007

i sometimes throw cables away

i mean straight into the bin without spending 10+ years in the box of might-come-in-handy-someday first

im a fucking monster

they're the same in C for historical reasons. iirc the C standard says the results of all shifts are implementation dependant, since many early architectures only had one or the other, or had neither but could fudge it using rotate instructions or whatever.

Bloody
Mar 3, 2013

arithmetic shifts are useless imvho

Spatial
Nov 15, 2007

in a microarch i worked on a while back i added the ability to do extending shifts in both directions. i.e. there's msb extending right shift and lsb extending left shift. :v:

one is useful for fixed point, the other is for generating masks quickly (also used in other instructions not just shifts)

Apocadall
Mar 25, 2010

Aren't you the guitarist for the feed dogs?

whats the best way to prevent interference to an EMG circuit? do i have to wrap my arm in a faraday cage?

BobHoward
Feb 13, 2012

The only thing white people deserve is a bullet to their empty skull

Spatial posted:

oh. well arithmetic shifts aren't that common. i've only used them for two reasons: fixed point arithmetic scaling while preserving signedness and for dynamically generating bitfield masks. this is part of why i suggested splitting arithmetic/logic shifts into separate operators, because sign extension is usually not what you want.

arithmetic shift is more common than you think below the level of an explicit language feature; compilers transform 'divide by a constant which is a power of 2' into shifts all the time

before anyone asks, yes they still do this even with hardware divide support. idk where it's at now, but last i paid any attention to it, a hardware divider with performance of 4 bits of output produced per clock cycle was considered good. a shift is usually much faster, and fully pipelined.

Bloody
Mar 3, 2013

Apocadall posted:

whats the best way to prevent interference to an EMG circuit? do i have to wrap my arm in a faraday cage?
what kinda interference? what's it's spectrum look like? broadly:
twist your pairs
common mode rejection
notch filter
peep this thing called right leg drive
better electrode contact (or just better electrodes)

Apocadall
Mar 25, 2010

Aren't you the guitarist for the feed dogs?

Bloody posted:

what kinda interference? what's it's spectrum look like? broadly:
twist your pairs
common mode rejection
notch filter
peep this thing called right leg drive
better electrode contact (or just better electrodes)

mains interference around 60hz, EMG signals are between 50hz and 3khz. voltages are between 1nV to 300nV and have to be amplified a lot to get a usable signal but last test i did i had so much noise that i couldn't get any sort of signal to show up on the scope. i got maybe one good spike in the hour i was hooked up to it.

a notch filter wont work because i need access to that band still, but i want to eliminate interference into that frequency i'm trying to read

https://en.wikipedia.org/wiki/Driven_right_leg_circuit
oh man i had no idea about this thing, thanks for the recommendation

electrodes i have no idea what to do about those, it was a pain in the rear end just getting what i do have, which are single use tabs that i run alligator clips to and then clip to the board, crappy but worked once (out of god knows how many tries). any ideas for better electrodes?

i'd test on something with higher voltage first like the heart beat but it's at a different frequency than what i'm aiming for

Apocadall
Mar 25, 2010

Aren't you the guitarist for the feed dogs?

it does look like there is a lot more available for electrodes now than there was when i got my last bag

Bloody
Mar 3, 2013

Apocadall posted:

mains interference around 60hz, EMG signals are between 50hz and 3khz. voltages are between 1nV to 300nV and have to be amplified a lot to get a usable signal but last test i did i had so much noise that i couldn't get any sort of signal to show up on the scope. i got maybe one good spike in the hour i was hooked up to it.

a notch filter wont work because i need access to that band still, but i want to eliminate interference into that frequency i'm trying to read

https://en.wikipedia.org/wiki/Driven_right_leg_circuit
oh man i had no idea about this thing, thanks for the recommendation

electrodes i have no idea what to do about those, it was a pain in the rear end just getting what i do have, which are single use tabs that i run alligator clips to and then clip to the board, crappy but worked once (out of god knows how many tries). any ideas for better electrodes?

i'd test on something with higher voltage first like the heart beat but it's at a different frequency than what i'm aiming for

uhhh if your signals are 1nV-300nV either you're not looking at EMG or your electrodes are hilariously bad ime

Bloody
Mar 3, 2013

you should be able to get muscle flexion pretty easily with any surface electrode pair, like if you stick one at the base of your thumb at the wrist and then up towards the top of that bigass thumb muscle you should expect to see lotsa bigass EMG signals in the 1s to 10s of mV range. i dont remember the frequency ranges off the top of my head but 50-3k sounds kinda high. i know you get tons of muscle artifacts in EEG, which is more like 1-50 Hz

what are you using for an amp?

Sagebrush
Feb 26, 2012

ERM... Actually I have stellar scores on the surveys, and every year students tell me that my classes are the best ones they’ve ever taken.

Sweevo posted:

if it compiles to a logical shift instruction then both are the same since logical shifting right puts zeros in at the left-hand side, so there's no need to zero them out later. whereas if it compiles to an arithmetic shift instruction then the left bits will be copies of the MSB of the input value (this preserves the sign in the result), so the leftmost bits might not be zero. it depends on the architecture/compiler, and whether or not the input value is declared as signed or unsigned. if you want it to be portable then shift+mask is more likely to be correct across different systems, but shifting alone is probably correct in 95% of cases.

well, it's running on a cortex-m4 and i'm operating only on uint32_ts. using the mask to ensure safety for signed types makes sense. is it one cycle slower to do that, though?

good to know that for this case it should work either way, though. that's what it seemed like but wanted to be sure.

on a related note, is this the right practice?

code:

void main() {
  uint32_t boobs;
  byte poop = byte foo(boobs>>24);
}

byte foo (byte bar) {
  return bar;
}

the function wants a byte, but i'm giving it a uint32 and shifting to recover the MSB. what is happening behind the scenes? is there a hidden internal conversion from uint32_t to byte? does it just select the last 8 bits of boobs after the shift? it *seems* to do what it's supposed to, but having not read the C reference, i'm unsure.

similarly, if i passed a pointer to boobs, would that also recover the MSB because it just reads the first 8 bits from that location?

Spatial
Nov 15, 2007

BobHoward posted:

arithmetic shift is more common than you think below the level of an explicit language feature; compilers transform 'divide by a constant which is a power of 2' into shifts all the time

before anyone asks, yes they still do this even with hardware divide support. idk where it's at now, but last i paid any attention to it, a hardware divider with performance of 4 bits of output produced per clock cycle was considered good. a shift is usually much faster, and fully pipelined.
i know. :) i was only talking about explicit usage of the operator.

4 bits per clock is still the norm. funnily enough the tiny arm cortex mcus have better division performance than x86 on a cycle for cycle basis: the cortex m3 does 32/32 bits in at most 12 cycles, while ivy bridge takes 25 cycles. of course in reality there's no competition because of the gulf in clock frequency. arm can afford to make the critical path much longer. but still i found this surprising when i worked with them at first.

a cool trick modern implementations do is reusing the bitscan/clz hardware to shortcut the division depending on the number of high bits set. because of this an m3 can pull off a division in just a few cycles if the operands are small. however it still can't compete with a shift, which will likely be combined with another operation for free thanks to the whole flexible operand2 thing in the isa.

Spatial
Nov 15, 2007

Sagebrush posted:

code:

void main() {
  uint32_t boobs;
  byte poop = byte foo(boobs>>24);
}

byte foo (byte bar) {
  return bar;
}

the function wants a byte, but i'm giving it a uint32 and shifting to recover the MSB. what is happening behind the scenes? is there a hidden internal conversion from uint32_t to byte? does it just select the last 8 bits of boobs after the shift? it *seems* to do what it's supposed to, but having not read the C reference, i'm unsure.
yes, there is an implicit narrowing conversion there. the result is truncated to fit the width of the target type.

at a low level this code would compile to something like:
- load boobs
- shift boobs right by 24 bits
- zero extend boobs to 8 bits
- call foo
- return

quote:

similarly, if i passed a pointer to boobs, would that also recover the MSB because it just reads the first 8 bits from that location?
to read only a byte you'd have to cast the pointer type to byte*. but it's not that simple. just for example if you wrote this:
code:
void main() {
  uint32_t boobs;
  byte poop = foo( (byte*) &boobs );
}

byte foo (byte* bar) {
  return *bar;
}
it won't do what you expect because of endianness. the m4 is little endian which means the byte order is reversed in memory compared to the layout of a register. accessing the first byte in memory will read the least significant byte of the value!

hobbesmaster
Jan 28, 2008

Spatial posted:

it won't do what you expect because of endianness. the m4 is little endian which means the byte order is reversed in memory compared to the layout of a register. accessing the first byte in memory will read the least significant byte of the value!

the cortex m4 itself is bi-endian, but I think most (all?) of them on the market are little endian only

Spatial
Nov 15, 2007

yeah, true

Poopernickel
Oct 28, 2005

electricity bad
Fun Shoe

Sagebrush posted:

well, it's running on a cortex-m4 and i'm operating only on uint32_ts. using the mask to ensure safety for signed types makes sense. is it one cycle slower to do that, though?

good to know that for this case it should work either way, though. that's what it seemed like but wanted to be sure.

on a related note, is this the right practice?

code:

void main() {
  uint32_t boobs;
  byte poop = byte foo(boobs>>24);
}

byte foo (byte bar) {
  return bar;
}

the function wants a byte, but i'm giving it a uint32 and shifting to recover the MSB. what is happening behind the scenes? is there a hidden internal conversion from uint32_t to byte? does it just select the last 8 bits of boobs after the shift? it *seems* to do what it's supposed to, but having not read the C reference, i'm unsure.

similarly, if i passed a pointer to boobs, would that also recover the MSB because it just reads the first 8 bits from that location?

I'm gonna blow your mind with this poo poo:
https://godbolt.org/

JawnV6
Jul 4, 2004

So hot ...

Poopernickel posted:

I'm gonna blow your mind with this poo poo:
https://godbolt.org/

yeah, just reduce to a snippet and see what actually happens for your target compiler/platform

like i honestly dont know what this means

Spatial posted:

- zero extend boobs to 8 bits
without context

registers (on a m4f?) are 32, the upper ones of which will be 0 after shifting and not need an explicit instruction, there are strb and strw instructions for store byte and store word if its going out to memory so even if the upper bits were polluted it wouldn't matter too much

Spatial
Nov 15, 2007

i wasn't talking about what the optimiser can theoretically produce. the question was about what the language actually means. when you assign a uint32 to a uint8 it means do a narrowing conversion, and UXTB (zero extend to 8 bits) is the most literal translation of that on ARMv7-M.

JawnV6
Jul 4, 2004

So hot ...

Spatial posted:

the question was about what the language actually means. when you assign a uint32 to a uint8 it means do a narrowing conversion, and UXTB (zero extend to 8 bits) is the most literal translation of that on ARMv7-M.

there's no zero extending to get the right shift of 32 by 24 to fill out 8 but ok sure

Spatial
Nov 15, 2007

duh. i'm giving the most general explanation.

don't be a nit picker

Sagebrush
Feb 26, 2012

ERM... Actually I have stellar scores on the surveys, and every year students tell me that my classes are the best ones they’ve ever taken.
well i am already significantly more confused but :cheers: anyway, i'm glad to know that basically as long as it's an unsigned type i don't really have anything to worry about

anyway, update on the vaporwave motorcycle instrument cluster: alpha version works!

https://www.youtube.com/watch?v=GoSAprKVoQg

got the whole thing finally assembled and installed and running with the v.0.1 code. still lots of UX things to work on, some industrial design changes I want to make, and lots of little details of calibration (temperature gauges, gamma table to balance the lighting, etc) but the basics do work!

i am particularly happy with that analog filter/comparator i built earlier using the advice in this thread. reminder: it takes the incredibly noisy ~350v signal from the spark plug coil and shapes it down to a clean 3.3v square wave with hysteresis so i can have a tachometer. i installed the thing, spent 30 seconds adjusting the trimpot to set the correct threshold, and bam -- beautiful and accurate and i took the bike on a 100 mile test ride and i don't think i saw a single tachometer glitch the entire time. it's so smooth and responsive that i don't even need to filter the data, though i am going to do a really small median filter or something to cut down on the flickering when it's right between two LEDs on the scale.




:stoke:

Rat Poisson
Nov 6, 2010

Sagebrush posted:

it's so smooth and responsive that i don't even need to filter the data, though i am going to do a really small median filter or something to cut down on the flickering when it's right between two LEDs on the scale.


are you planning to do some filtering or rounding-off of the numeric RPM value? the current output seems visually distracting as the 10's and 1's digits bounce around, so maybe rounding it off to the nearest 50 or 100 RPM for display? the project looks great though.

Raluek
Nov 3, 2006

WUT.
amber lcd looks great

is the wireframe grid movement speed going to vary with actual wheel speed? or at least stop when the bike is stopped?

also maybe consider not using red for the bottom of the RPM scale, keep that for near/at redline? usually to me red on an instrument cluster is an "oh poo poo" color.

Spatial
Nov 15, 2007

pretty drat cool :)

Adbot
ADBOT LOVES YOU

Sagebrush
Feb 26, 2012

ERM... Actually I have stellar scores on the surveys, and every year students tell me that my classes are the best ones they’ve ever taken.
Yeah definitely going to round the rpm to the nearest something-or-other. It's fairly distracting as is, not to mention impossible to read. Minor details, though -- that's like 10 lines of code obv.

Right now the tachometer cycles through red/amber/green/amber/red as it goes through the power band, but I'm thinking of making it just monochrome with red at the redline, yeah. Infinite options for color-coding stuff like that. Personally I would have liked for the whole system to be red, but these OLEDs are only available in green and amber :shrug:

  • Locked thread