DSPRelated.com
Forums

Conceptual model for pointer arithmetic in FIR filter implementation?

Started by Chris Bore October 13, 2004
Chris Bore wrote:

> The question of 'DSP is always done with DSP processors' is > interesting. What about VLIWs? FPGAs? I've been very interested for > the past few years in a lot of work being done using fast parallel > architectures to do DSP-like things (specifically, video processing, > audio compression and de-compression, etc). These devices do not have > MAC units or autoincrement registers but they do run at 9 GOPS and > they are used routinely (in set top boxes and TVs) to do real time > processing on audio, video and other signals at rates up to 108 MHz. > At the other end of the scale, much low-power audio DSP is in fact > done on ARM processors. So I am less sure than I used to be that DSP > is about the rather narrow range of DSP processors from the main > stables. > > Chris > ===================================== > Chris Bore > BORES Signal Processing > www.bores.com > chris@bores.com
There's plenty of DSP done on Windows boxes and Macs, too. My comments at least arose from an attempt to guess what your course is likely to be about. However wrong I might have been, it's nice to hear from you again. Jerry -- Engineering is the art of making what you want from things you can get. �����������������������������������������������������������������������
"Chris Bore" <chris_bore@yahoo.co.uk> wrote in message
news:468debd2.0410150558.e2a056c@posting.google.com...
> The question of 'DSP is always done with DSP processors' is > interesting. What about VLIWs? FPGAs? I've been very interested for > the past few years in a lot of work being done using fast parallel > architectures to do DSP-like things (specifically, video processing, > audio compression and de-compression, etc). These devices do not have > MAC units or autoincrement registers but they do run at 9 GOPS and > they are used routinely (in set top boxes and TVs) to do real time > processing on audio, video and other signals at rates up to 108 MHz. > At the other end of the scale, much low-power audio DSP is in fact > done on ARM processors. So I am less sure than I used to be that DSP > is about the rather narrow range of DSP processors from the main > stables.
Hi Chris Now that we've convinced you that comp.dsp is worth a visit atleast once a day...we'd sure love to see more posts from you. In response to your question - I've also had similar questions. There are 2 approaches to answering your questions. If I care (you should probably extend this to "if the organization I work for cares") about readability of the implementation, then I'd say that an implementation approach that starts from the math is preferable. However, if this approach isn't going to get the job done (not fast enough), then one might have to start departing from this approach quickly. Now - if one is working on DSP algorithms that run on non traditional processors, would you expect that 'C' is still being used to implement it? I know there are several people who are working on software that allows C programs to get compiled into FPGA implemenations. In that case, I'd say that the onus is on these people (compilers) to ensure that the math notation is transformed optimally into the target device's architecture. I don't know how to interpret your first post for, say, someone working on implementing an FIR on an FPGA. In this case, the algorithm maps quite differently into the chip and the person would have to think differently when implementing the same algorithm. I'm not sure if said anything useful, but I got my one post for the day in :-) Cheers Bhaskar
> Chris > ===================================== > Chris Bore > BORES Signal Processing > www.bores.com > chris@bores.com > > Tim Wescott <tim@wescottnospamdesign.com> wrote in message
news:<10mrbdnh6ld0927@corp.supernews.com>...
> > glen herrmannsfeldt wrote: > > > > > > > > > Jerry Avins wrote: > > > > > > (mostly previously snipped discussion about array and pointer > > > notation in C) > > > > > >> I don't want to be seen as arguing against this, but it doesn't
really
> > >> make sense to me. I'd like to say why not, and be educated. > > > > > > > > >> It seems to me that the natural way to write that code in assembler > > >> (which is my model of "what the machine does") is by loading an
address
> > >> into an autoincrement register and fetching successive elements as > > >> needed. "x = *pointer++" is practically a paraphrase of that. > > > > > > > > > Well, that assumes that you have an autoincrement register. > > > There is discussion over which came first, the PDP-11 > > > autoincrement addressing mode or C's ++ operator, but it > > > does make sense on the PDP-11, especially with only eight > > > registers including SP and PC. VAX has autoincrement mode, > > > and also good indexed modes. You probably don't use either > > > of those very often. > > > > On a DSP? Oh yes you do. If it doesn't have a MAC instruction that > > lets you multiply two numbers, add the result to an accumulator, load > > their temporary registers, increment their pointers (and possibly wrap > > them in hardware) all in one clock cycle -- then it's a poor excuse for > > a DSP. > > > > > > > The array > > > > >> approach would put the base address on a fixed register and use
indexed
> > >> addressing with an autoincrement autoincrement register. That's two > > >> registers instead of one, with the possibility that the compiler will > > >> actually calculate an effective address at run time for each
reference.
> > >> That would not only be slow, but conceptually cumbersome. > > > > > > > > > Well, first of all the OP gave two programs that will both > > > compile the same way, though one looked pointer like and one > > > array like. Many processors now have indexed addressing modes > > > that scale by the size of the item addressed, and have enough > > > registers that it doesn't matter so much. The loop variable > > > needs to be in a register already, so it really isn't another > > > register. Most likely any extra computation can be done > > > during the time needed to do the memory load/store. > > > > > > Well, this was on comp.arch not so long ago. RISC processors > > > don't tend to have autoincrement mode, and, except for a few > > > special instructions, x86 doesn't, either. Then there is the > > > question of which notation the optimizers recognize. > > > > > > -- glen > > > > > But digital signal processors do, and this is comp.dsp.

Chris Bore wrote:

> I remember how good a newsgroup comp.dsp was - I drifted away a few > years ago but am glad to be back. Thank you for informed and helpful > responses.
> Yes, the two ways of writing code are equivalent. When I questioned > the author, he gave a plausible explanation. He allocates the memory > dynamically, so declares y (for instance) as a pointer (which malloc > will then return pointing to the allocated memory) - and so decided it > was consistent to stick with the way he declared. I am not convinced - > Kernighan has many examples where he declares a pointer but uses it > like an array, presumably precisely because it is the same - but there > is a certain logic to it.
I believe it is extremely rare in C to use the *(a+n) notation. Now, sometimes I prefer a+n to the possibly more common &a[n], for example as an argument to scanf(). The n[a] notation is somewhat popular for IOCCC (International obfuscated C coding contest) entries, even using i["abcd"] notation to index a constant. To continue to higher dimensions, a[i][j] == *(a+i)[j] == *(*(a+i)+j) == *(j+*(i+a)) == j[*(i+a)] == j[i[a]] == *(*(i+a)+j) == i[a][j]
> I used to advocate writing C that 'matched the architecture'- hence > the explanations of this on our web course - but I am less convinced > now. Compilers will do this, and I think most now do - anyway, the > programmer should not assume that certain C will result in definite > assembler. I am also now much more aware that not all DSP is done on > 'DSP Procesors' nor even in C.
I wasn't even sure if the newsgroup was named for signal processing or signal processors.
> I'm more interested now because I have been dealing with DSP on > non-traditional DSPs (eg VLIW, conventional RISC) for some time, and > in environments where code readability and separation of code from > architecture (implementation) is MUCH more highly valued than > (sometimes only imagined) efficiency. So my question was to gain the > views of a community I respect (comp.dsp) and the responses remind me > that I should participate here more often.
> There was one other part to the question, though - is there an > intuitively compelling, and 'math/application-oriented', conceptual > model of DSP that would use pointers to lists rather thn elements of > arrays as its basic model?
The distinction is more important when they are not elements of a single array. For example, going down a linked list: for(p=head; *p; p=p->next) printf("%s\n",p->name); List elements can be allocated separately, or in small groups to improve efficiency. The C strcpy() function can be implemented as: while(*s++=*p++) ; On a PDP-11 it might compile to a tight loop, though it might be that an assembly implementation would be faster. -- glen

Bhaskar Thiagarajan wrote:
(snip)

> If I care (you should probably extend this to "if the organization I work > for cares") about readability of the implementation, then I'd say that an > implementation approach that starts from the math is preferable. However, if > this approach isn't going to get the job done (not fast enough), then one > might have to start departing from this approach quickly.
> Now - if one is working on DSP algorithms that run on non traditional > processors, would you expect that 'C' is still being used to implement it? I > know there are several people who are working on software that allows C > programs to get compiled into FPGA implemenations. In that case, I'd say > that the onus is on these people (compilers) to ensure that the math > notation is transformed optimally into the target device's architecture.
> I don't know how to interpret your first post for, say, someone working
> on implementing an FIR on an FPGA. In this case, the algorithm maps quite > differently into the chip and the person would have to think differently > when implementing the same algorithm.
It is exactly this reason why I don't like the idea of C as a hardware description language. Verilog and VHDL, like hardware, have the basic idea that everything happens all the time. While there are attempts to make a parallel programming language out of C, it is very different from the thought process for designing a hardware implementation of most algorithms. -- glen
Chris Bore wrote:

> The question of 'DSP is always done with DSP processors' is > interesting. What about VLIWs? FPGAs? I've been very interested for > the past few years in a lot of work being done using fast parallel > architectures to do DSP-like things (specifically, video processing, > audio compression and de-compression, etc). These devices do not have > MAC units or autoincrement registers but they do run at 9 GOPS and > they are used routinely (in set top boxes and TVs) to do real time > processing on audio, video and other signals at rates up to 108 MHz. > At the other end of the scale, much low-power audio DSP is in fact > done on ARM processors. So I am less sure than I used to be that DSP > is about the rather narrow range of DSP processors from the main > stables. >
-- snip -- I suspect there's more DSP done with non-DSP chips than with DSP chips, and quite usefully and sensibly, too. DSP chips are really quite useful for problems that fall in their speed range, and significantly extend the capability of a programmed processor to do DSP. At the low end, however, they're more expensive than general purpose processors, and they need extra care and feeding to get the advantage of that MAC instruction. At the high end (video rates) you start really pressing the processor, and dollar for dollar you can do better with an ASIC or FPGA. I have used regular microcontrollers, from 8-bit to 32-bit, for coding control systems at sub-audio sample rates. I've specified algorithms to be implemented on FPGAs (I'm not a hot-shot FPGA designer). And finally, I've used actual DSP chips for signal processing at audio rates. All have worked well, and each approach has its own advantages and disadvantages. So I tend to think of the DSP chip as a tool that may or may not be the right choice when I have a DSP problem to solve, and if I get into the design process early enough I evaluate the range of possible solutions for the best one at hand. -- Tim Wescott Wescott Design Services http://www.wescottdesign.com
Chris Bore wrote:

> Jerry Avins <jya@ieee.org> wrote in message news:<2t5lg5F1rgltnU1@uni-berlin.de>... > >>Jon Harris wrote: >> >> >>>I tend to agree with JaaC and Glen. To me, the pointer notation obfuscates the >>>math/DSP concepts. If you are teaching a class on the C language, then show the >>>pointer method. But for understanding DSP, go with the array method. If you >>>want to throw in the pointer method at the end as an alternate coding method >>>that _might_ be more efficient in some cases, then do so. I wouldn't make a big >>>deal about it, but it might be nice to mention it because the students may come >>>across it when looking at other's code in the future. >> >>I don't want to be seen as arguing against this, but it doesn't really >>make sense to me. I'd like to say why not, and be educated. >> >>It seems to me that the natural way to write that code in assembler >>(which is my model of "what the machine does") is by loading an address >>into an autoincrement register and fetching successive elements as >>needed. "x = *pointer++" is practically a paraphrase of that. The array >>approach would put the base address on a fixed register and use indexed >>addressing with an autoincrement autoincrement register. That's two >>registers instead of one, with the possibility that the compiler will >>actually calculate an effective address at run time for each reference. >>That would not only be slow, but conceptually cumbersome. >> >>Where has my thinking gone astray? >> >>Jerry
> Thanks, Jerry. > > I do not think your thinking has gone astray. But is it thinking from > just one side of the problem? The pointer notation is in fact close to > the hardware model of what happens (provided the architecture is > indeed what the programmer thinks it is). Which is helpful for a > programmer thinking 'how do I implement this?'. But it is not close to > the way the math would be written. So if you are coming up from the > hardware implementation the pointers make sense, whereas if you are > coming down from the math they may not be so immediately obvious. > > A second point is perhaps, that the C code here is written with > assumptions about the underlying architecture (the programmer who > wrote this explained to me that 'all DSP processors work like this..'). > For example a particular processor may not offer an autoincrement > register - VLIWs typically don't. So the assumption may be too narrow: > 'all DSP programs are written for DSP processors and all DSP > processors have this simple architecture so this code will result in > efficient use of the machine....'. > Actually the code in your original post is _not_ written the way an autoincrement machine might do it. What most DSP chips worthy of the name do is something like: for (n = endCount; --n;) accumulator += (*x++) * (*y++); -- and that's ignoring the any circular buffers that you may have set up! Up until a few years ago the above code snippet would have been slightly faster than what you have in your original post (and yes, I know the functionality is a bit different). I honestly don't know if compilers less than 5 years old can go from your post's arrangement to mine -- I do know that TI's compiler for the '2812 is distressingly unable to optimize it's way to a MAC instruction, so that must be written in assembly. -- Tim Wescott Wescott Design Services http://www.wescottdesign.com
Chris Bore wrote:

> I remember how good a newsgroup comp.dsp was - I drifted away a few > years ago but am glad to be back. Thank you for informed and helpful > responses. > > Yes, the two ways of writing code are equivalent. When I questioned > the author, he gave a plausible explanation. He allocates the memory > dynamically, so declares y (for instance) as a pointer (which malloc > will then return pointing to the allocated memory) - and so decided it > was consistent to stick with the way he declared. I am not convinced - > Kernighan has many examples where he declares a pointer but uses it > like an array, presumably precisely because it is the same - but there > is a certain logic to it. > > I used to advocate writing C that 'matched the architecture'- hence > the explanations of this on our web course - but I am less convinced > now. Compilers will do this, and I think most now do - anyway, the > programmer should not assume that certain C will result in definite > assembler. I am also now much more aware that not all DSP is done on > 'DSP Procesors' nor even in C. > > I'm more interested now because I have been dealing with DSP on > non-traditional DSPs (eg VLIW, conventional RISC) for some time, and > in environments where code readability and separation of code from > architecture (implementation) is MUCH more highly valued than > (sometimes only imagined) efficiency. So my question was to gain the > views of a community I respect (comp.dsp) and the responses remind me > that I should participate here more often. > > There was one other part to the question, though - is there an > intuitively compelling, and 'math/application-oriented', conceptual > model of DSP that would use pointers to lists rather thn elements of > arrays as its basic model? > > Thanks very much, > > Chris > >
I generally code with the rule that the code should, overall, be as readable as possible, and one should only sacrifice readability for efficiency if absolutely necessary (and then bury it underneath an easy-to-use and readable interface!). As far as that code it would be a tossup between wanting to make _sure_ that follow-on coders _knew_ that I was using dynamic pointer rather than an array and making it more readable for Pascal programmers (did I say that?). -- Tim Wescott Wescott Design Services http://www.wescottdesign.com
As to the question whether real DSP on non-traditional architectures
is done in C, then yes very much so - most of Philips and Sony work on
audio and video for digital and analog TV is done in C, even in C++ -
this at least for the Nexperia processors. They use VLIW for this. The
compilers become enormously expensive (hundreds of man-years of
effort) and the code base becomes highly valuble (hunderds of millions
of dollars) - so the software tools start to cost almost as much as
the system-on-chip itself. The software teams are also large - I think
Philips have upwards of 600 software engineers working on their next
generation digital TV software in C.

This leads to an interesting thing - programmer who are more used to
big software engineering projects, and workstation environments, now
working on embedded systems where speed and code size are important.
Hence in part the desire to separate interface (used by these people)
from implementation (done by experts and often through the compiler).

I've been working for the past few years with Philips Nexperia DSPs.
These don't get used as much as more traditional DSPs in terms of the
number of users, but they do go into a lot of consumer electronics (I
think all new Philips and Sony digital TVs do their audio and video
processing using Nexperia chips). Returning to the topic of
traditional DSP in revising a DSP class we have taught for many years,
I find I have learnt new habits. For these consumer electronics
companies, software re-use and time-to-market is king and so enormous
investment is put into compiler efficiency so the programmers can
separate interface from implementation. But at the same time, they do
adopt a layered approach that means a programmer faced with a truly
time-demanding program task with which the compiler can't cope can go
into as much specific optimization as necessary - but still required
to provide a very simple interface to whoever uses their program
module. I've also learnt that optimization costs a lot - and is often
done to parts of a program that don't matter (many programmers in
practice spend weeks optimizaing a piece of code that in the first
place only took up 1% of the total time).

I am now struggling to fully understand these questions of 'code to
the hardware' versus 'code to the application' and trying to see what
real practical guidance one can offer.

Chris
=========================
Chris Bore
BORES Signal Processing
chris@bores.com
www.bores.com

"Bhaskar Thiagarajan" <bhaskart@my-deja.com> wrote in message news:<2tag2gF1to5fiU1@uni-berlin.de>...
> "Chris Bore" <chris_bore@yahoo.co.uk> wrote in message > news:468debd2.0410150558.e2a056c@posting.google.com... > > The question of 'DSP is always done with DSP processors' is > > interesting. What about VLIWs? FPGAs? I've been very interested for > > the past few years in a lot of work being done using fast parallel > > architectures to do DSP-like things (specifically, video processing, > > audio compression and de-compression, etc). These devices do not have > > MAC units or autoincrement registers but they do run at 9 GOPS and > > they are used routinely (in set top boxes and TVs) to do real time > > processing on audio, video and other signals at rates up to 108 MHz. > > At the other end of the scale, much low-power audio DSP is in fact > > done on ARM processors. So I am less sure than I used to be that DSP > > is about the rather narrow range of DSP processors from the main > > stables. > > Hi Chris > > Now that we've convinced you that comp.dsp is worth a visit atleast once a > day...we'd sure love to see more posts from you. > In response to your question - I've also had similar questions. There are 2 > approaches to answering your questions. > If I care (you should probably extend this to "if the organization I work > for cares") about readability of the implementation, then I'd say that an > implementation approach that starts from the math is preferable. However, if > this approach isn't going to get the job done (not fast enough), then one > might have to start departing from this approach quickly. > Now - if one is working on DSP algorithms that run on non traditional > processors, would you expect that 'C' is still being used to implement it? I > know there are several people who are working on software that allows C > programs to get compiled into FPGA implemenations. In that case, I'd say > that the onus is on these people (compilers) to ensure that the math > notation is transformed optimally into the target device's architecture. I > don't know how to interpret your first post for, say, someone working on > implementing an FIR on an FPGA. In this case, the algorithm maps quite > differently into the chip and the person would have to think differently > when implementing the same algorithm. > I'm not sure if said anything useful, but I got my one post for the day in > :-) > > Cheers > Bhaskar > > > > > Chris > > ===================================== > > Chris Bore > > BORES Signal Processing > > www.bores.com > > chris@bores.com > > > > Tim Wescott <tim@wescottnospamdesign.com> wrote in message > news:<10mrbdnh6ld0927@corp.supernews.com>... > > > glen herrmannsfeldt wrote: > > > > > > > > > > > > Jerry Avins wrote: > > > > > > > > (mostly previously snipped discussion about array and pointer > > > > notation in C) > > > > > > > >> I don't want to be seen as arguing against this, but it doesn't > really > > > >> make sense to me. I'd like to say why not, and be educated. > > > > > > > > > > > >> It seems to me that the natural way to write that code in assembler > > > >> (which is my model of "what the machine does") is by loading an > address > > > >> into an autoincrement register and fetching successive elements as > > > >> needed. "x = *pointer++" is practically a paraphrase of that. > > > > > > > > > > > > Well, that assumes that you have an autoincrement register. > > > > There is discussion over which came first, the PDP-11 > > > > autoincrement addressing mode or C's ++ operator, but it > > > > does make sense on the PDP-11, especially with only eight > > > > registers including SP and PC. VAX has autoincrement mode, > > > > and also good indexed modes. You probably don't use either > > > > of those very often. > > > > > > On a DSP? Oh yes you do. If it doesn't have a MAC instruction that > > > lets you multiply two numbers, add the result to an accumulator, load > > > their temporary registers, increment their pointers (and possibly wrap > > > them in hardware) all in one clock cycle -- then it's a poor excuse for > > > a DSP. > > > > > > > > > The array > > > > >> approach would put the base address on a fixed register and use > indexed > > > >> addressing with an autoincrement autoincrement register. That's two > > > >> registers instead of one, with the possibility that the compiler will > > > >> actually calculate an effective address at run time for each > reference. > > > >> That would not only be slow, but conceptually cumbersome. > > > > > > > > > > > > Well, first of all the OP gave two programs that will both > > > > compile the same way, though one looked pointer like and one > > > > array like. Many processors now have indexed addressing modes > > > > that scale by the size of the item addressed, and have enough > > > > registers that it doesn't matter so much. The loop variable > > > > needs to be in a register already, so it really isn't another > > > > register. Most likely any extra computation can be done > > > > during the time needed to do the memory load/store. > > > > > > > > Well, this was on comp.arch not so long ago. RISC processors > > > > don't tend to have autoincrement mode, and, except for a few > > > > special instructions, x86 doesn't, either. Then there is the > > > > question of which notation the optimizers recognize. > > > > > > > > -- glen > > > > > > > But digital signal processors do, and this is comp.dsp.
Chris Bore wrote:

> They use VLIW for this.
How do you pronounce "VLIW"? Do you articulate each letter separately, or is there an idiom making a "word" of it? Martin
Chris Bore wrote:

> As to the question whether real DSP on non-traditional architectures > is done in C, then yes very much so - most of Philips and Sony work on > audio and video for digital and analog TV is done in C, even in C++ - > this at least for the Nexperia processors. They use VLIW for this. The > compilers become enormously expensive (hundreds of man-years of > effort) and the code base becomes highly valuble (hunderds of millions > of dollars) - so the software tools start to cost almost as much as > the system-on-chip itself. The software teams are also large - I think > Philips have upwards of 600 software engineers working on their next > generation digital TV software in C. > > This leads to an interesting thing - programmer who are more used to > big software engineering projects, and workstation environments, now > working on embedded systems where speed and code size are important. > Hence in part the desire to separate interface (used by these people) > from implementation (done by experts and often through the compiler). > > I've been working for the past few years with Philips Nexperia DSPs. > These don't get used as much as more traditional DSPs in terms of the > number of users, but they do go into a lot of consumer electronics (I > think all new Philips and Sony digital TVs do their audio and video > processing using Nexperia chips). Returning to the topic of > traditional DSP in revising a DSP class we have taught for many years, > I find I have learnt new habits. For these consumer electronics > companies, software re-use and time-to-market is king and so enormous > investment is put into compiler efficiency so the programmers can > separate interface from implementation. But at the same time, they do > adopt a layered approach that means a programmer faced with a truly > time-demanding program task with which the compiler can't cope can go > into as much specific optimization as necessary - but still required > to provide a very simple interface to whoever uses their program > module. I've also learnt that optimization costs a lot - and is often > done to parts of a program that don't matter (many programmers in > practice spend weeks optimizaing a piece of code that in the first > place only took up 1% of the total time). > > I am now struggling to fully understand these questions of 'code to > the hardware' versus 'code to the application' and trying to see what > real practical guidance one can offer. > > Chris > ========================= > Chris Bore > BORES Signal Processing > chris@bores.com > www.bores.com
They might do well to look into what Forth can do for them. You might enjoy a conversation with MicroProcessor Engineering in England: Stephen Pelc, stephenXXX@INVALID.mpeltd.demon.co.uk MicroProcessor Engineering Ltd - More Real, Less Time 133 Hill Lane, Southampton SO15 5AF, England tel: +44 (0)23 8063 1441, fax: +44 (0)23 8033 9691 web: http://www.mpeltd.demon.co.uk - free VFX Forth downloads Here in the US, talk to Forth, Inc.: Elizabeth D. Rather (US & Canada) 800-55-FORTH FORTH Inc. +1 310-491-3356 5155 W. Rosecrans Ave. #1018 Fax: +1 310-978-9454 Hawthorne, CA 90250 http://www.forth.com "Forth-based products and Services for real-time applications since 1973." Jerry -- Engineering is the art of making what you want from things you can get. &#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;&#4294967295;