Winston Gutkowski wrote:
Stevens Miller wrote:What is absolute, hard, undeniable fact, however, is that Java's lack of unsigned integral primitives is a major pain in my backside.
Actually, you do: - char - and it works just as you'd expect an unsigned short to...
The problem is that without those final casts, it attempts to print it out as a character.
I suspect there's also a lot of promotion to int going on behind the scenes; but that would be the case for any smaller primitive.
"Il y a peu de choses qui me soient impossibles..."
Stevens Miller wrote:But pixels aren't made of shorts, they're made of bytes...
"Leadership is nature's way of removing morons from the productive flow" - Dogbert
Articles by Winston can be found here
Winston Gutkowski wrote:
Stevens Miller wrote:But pixels aren't made of shorts, they're made of bytes...
Ooof, really? Sounds like Mr.Blobby time to me; but maybe it's part of that wonderful spec that is NTSC (Note: != PAL...by a long chalk)
Computer screens have been at least 16-bit for more than 20 years, and 32-bit for at least 10 (I know because my clunky old Dell is 7 years old, and it wasn't new then).
It also sounds to me like you're moaning about the fact that Java's basic unit of operation is an int, rather than the fact that it's unsigned. Bitwise operations (apart from '>>') couldn't give a toss about them.
Not being an expert on these things, I don't know; but couldn't you get more throughput by dealing with your pixels 4 at a time?
Winston
"Il y a peu de choses qui me soient impossibles..."
Campbell Ritchie wrote:Actually those two bitwise operations can possibly be completed in two clock cycles. Both >> and & are very fast. I am pretty sure you can do & in one clock cycle.
"Il y a peu de choses qui me soient impossibles..."
Campbell Ritchie wrote:The trouble with unpackedBytes[index][2] is that you are turning an int[] (or int*) into a byte[][] (or char[][] or char**). To do that you have to abandon checking the type of the array, or even the size of the array, and as we all know, overflowing the size of an array can produce rubbish results or even allow malware into memory. So the price you pay for type‑safety is (unpackedBytes[index] >> 0x20) & 0xff
Can you display all 24 bits together, or do you have to separate the three R G and B bytes as they go to the screen? I presume from previous discussion that the answer is no.
James Gosling wrote:Quiz any C developer about unsigned, and pretty soon you discover that almost no C developers actually understand what goes on with unsigned, what unsigned arithmetic is.
Yes, it would probably have been a lot easier for you if we had an unsigned keyword. I agree there.
"Il y a peu de choses qui me soient impossibles..."
Stevens Miller wrote:I realized there truly is no alternative in Java to shifting and masking...
"Leadership is nature's way of removing morons from the productive flow" - Dogbert
Articles by Winston can be found here
Winston Gutkowski wrote:
Stevens Miller wrote:I realized there truly is no alternative in Java to shifting and masking...
You'll have to forgive me for my ignorance (despite your kind words ), but I was under the impression that even in C, bitwise operation are still the quickest (although possibly not as beneficial, timewise, as in Java), so if you can say '<< 1' rather than '* 2', you may be saving a few cycles.
1. How fast you can read the input (and that will involve I/O and network pipelines).
2. How fast you can process that input.
3. How fast you can write (or stream) it to wherever it is needed.
and your focus appears to be entirely on point (2).
I can understand your thinking because, as a Java programmer, that is basically the only area that you have any control over; however, there comes a point at which (2) will be fast enough - ie, at which your program, which may historically have been the bottleneck to the process, either
(a) has been fully optimized, or
(b) (and this, to me, is programming Nirvana) has been optimized sufficiently that it is no longer a bottleneck without compromising design.
So, what can my program do? It can process its data in the quickest way possible; and in Java the simplest way to do that is by making every numeric entity (and your data would seem to comprise of nothing but) involved in a numeric operation an int.
Memory, as we both know, is cheap and, above all, fast; so I can't imagine that the business of expanding bytes to ints, or contracting them at the other end, of a memory-based pipeline, is going to add anything more than a fixed and measurable overhead to the process; and furthermore, it can probably be threaded.
What you do with those numbers in the middle and how you do it is entirely up to you.
Like I say, I've never had to deal with the problem that you are, but I do wonder if you're not focusing on too small an area when it comes to optimization.
"Il y a peu de choses qui me soient impossibles..."
Stevens Miller wrote:Now, maybe I've been programming graphics stuff too long, but, when I saw that bytes are always [-128, 127], and never [0, 255], I not only got frustrated, but I did wonder, "What good is a signed type with a range like that? Who would use it? For what?" In my experience, the only use I've ever made of eight-bit data types has been for pixel color values (unsigned, by their very nature) and for storing text characters (also unsigned, by their very nature). I'm still curious: what good is a signed byte? Putting my question another way, if bytes are always going to be signed, why have bytes at all?
"Leadership is nature's way of removing morons from the productive flow" - Dogbert
Articles by Winston can be found here
Winston Gutkowski wrote:Well, I have done a little bit of work (and timing) on lots of bitwise operations recently, and I know they're pretty darn quick; so I though I'd check out a few things for you on my clunky old Dell.
The difference between a loop that does nothing and one that assigns an unsigned byte value (ie, b & 0xFF) to an int?
about .36 of a nanosecond - that is 0.36 seconds difference over 1 billion iterations.
Then I assigned it (still unsigned) to a 64K cyclically indexed int buffer: .75 of a nanosecond.
"Il y a peu de choses qui me soient impossibles..."
Greg Charles wrote:The way I look at it, Java is an excellent applications programing language, and C is an excellent systems programing language, and never the twain shall meet.
Back when I used C++ for application programing, it was pretty common to find a bug where someone compared a signed value to an unsigned value and got unexpected results. In fact, Lint used to advertise in Dr. Dobbs every week with little "find the bug" puzzles, and unsigned/signed errors were a pretty common theme.
These weren't stupid developers; it was just an easy mistake to make, especially as C allows typedefs, which may obscure whether a type is signed or not, and C++ allows operators to work on classes, so the definition of the storage type can be really obscured. I think that's what James Gosling meant. Developers certainly understand what unsigned and signed integers are, but they might not fully appreciate the dangers of mixing signed and unsigned types in an application. C++ fails, in my opinion, because it tries to turn C into an applications programing language without removing its systems programing features.
Similarly, you are using Java for what I would call a systems programing job. Because of that, you are hitting the reverse of the problems that C++ has. I think doing some of your work in native functions developed in C, or, hell, assembly, makes a lot of sense. If you're not using the right tool for the job, the fault isn't the tool's.
BTW, this is a very interesting thread. Thanks for that!
Stevens Miller wrote:
Greg Charles wrote:Similarly, you are using Java for what I would call a systems programing job. Because of that, you are hitting the reverse of the problems that C++ has. I think doing some of your work in native functions developed in C, or, hell, assembly, makes a lot of sense. If you're not using the right tool for the job, the fault isn't the tool's.
Ahem. Image processing is hardly systems programming.
Stevens Miller wrote:Yup, those numbers are roughly what I got in my tests (implicitly doubled, since you have to pack your bytes back again)
I mean, Winston... use a multi-core, multi-threaded (and you haven't mentioned how I synch this or the overhead involved in that yet) approach, just so I can get my bytes into ints? As a work-around for the fact that C has "unsigned byte" and Java doesn't? With all due respect, my colleague, are you kidding me?
"Leadership is nature's way of removing morons from the productive flow" - Dogbert
Articles by Winston can be found here
Steve Luke wrote:
Stevens Miller wrote:
Greg Charles wrote:Similarly, you are using Java for what I would call a systems programing job. Because of that, you are hitting the reverse of the problems that C++ has. I think doing some of your work in native functions developed in C, or, hell, assembly, makes a lot of sense. If you're not using the right tool for the job, the fault isn't the tool's.
Ahem. Image processing is hardly systems programming.
I think I agree with Greg here. What you are doing is not image processing in the traditional sense where speed only sort of matters in terms of responsiveness to the user. You are really programming an extension to the webcam, need to worry on a low level about system resources, and need to concentrate on an effective algorithm that can take full advantage of the hardware (the camera, and CPU) with minimal overhead. There is a gray line between system programming and application programming but I think based on what I read in this thread, your app leans on the system side.
Winston Gutkowski wrote:
Stevens Miller wrote:Yup, those numbers are roughly what I got in my tests (implicitly doubled, since you have to pack your bytes back again)
Wrong. Again, you're thinking like a C programmer. You bang those ints out to another buffer and let another thread deal with compacting them.
I mean, Winston... use a multi-core, multi-threaded (and you haven't mentioned how I synch this or the overhead involved in that yet) approach, just so I can get my bytes into ints? As a work-around for the fact that C has "unsigned byte" and Java doesn't? With all due respect, my colleague, are you kidding me?
Actually, as I said before, the "unsigned" part has nothing (or very little) to do with it. The problem you're running into is that Java's basic unit of numeric operation is an int.
And what processor these days isn't multi-core? Or at the very least dual core. The fact is that in Unix, the standard pipe symbol (|) would do exactly what I'm talking about (ie, separate the processes of input, process and output) automatically; and in Java threading is a lot easier than it is in C/C++. By forcing everything into a single thread you've just prevented the OS (or JVM) from doing any parallel processing for you, so your latency will always be determined by the sum of the operations involved.
And synching is entirely up to you. If you make your buffers 64 meg instead of 64k, surely to God it's a relatively easy matter to 'chunk' your stream I/O so that sync points only occur every 64 or 128k? That's precisely how buffered I/O works.
If I've got time over the weekend I may try out some simple thoughput tests of threaded and non-threaded solutions (and they will be simple; I ain't writin' no real-time video pixel-mangler ), but I honestly think that you're obsessing on a very small part of your overall problem.
"Il y a peu de choses qui me soient impossibles..."
Stevens Miller wrote:I would say it is much closer to a game or real-time simulator. But, I would also say that supports your "gray line" point. However, it is interesting to note that Winston is making suggestions from the "Java is the right tool for what you are doing" perspective, while, Steve is saying "Java is not the right tool for what you are doing."
Stevens Miller wrote:...Does what I want in C. In Java, it only works if p1 < 128 and p2 < 128.
"Leadership is nature's way of removing morons from the productive flow" - Dogbert
Articles by Winston can be found here
Winston Gutkowski wrote:
Stevens Miller wrote:...Does what I want in C. In Java, it only works if p1 < 128 and p2 < 128.
Or both are >= 128.
OK, so they have to be masked, which adds about .35 to the op if you're not prepared to convert.
I also tested the same op with shorts and chars, and the results are so close to int that I can't really make any definitive judgement; although char is generally the quickest - which suggests another solution: why not just use a Reader and Writer and deal with the pixels as characters? Then you're guaranteed unsigned results, and you may save some time on sheer volume.
Fun stuff.
"Il y a peu de choses qui me soient impossibles..."
Winston Gutkowski wrote:
Stevens Miller wrote:I would say it is much closer to a game or real-time simulator. But, I would also say that supports your "gray line" point. However, it is interesting to note that Winston is making suggestions from the "Java is the right tool for what you are doing" perspective, while, Steve is saying "Java is not the right tool for what you are doing."
I'm not sure I was saying that. What I'm saying is that you may not be focusing on the right areas if you want to do it in Java (and this is, after all, a Java forum). I suspect that the number crunching probably is quicker in C/C++ than in Java - and you don't have to worry about converting your streams - but how much quicker I have no idea (I suspect it's less than you think, though). A Java version is probably a lot more portable as well.
Stevens Miller wrote:Sorry if that's a boring history lesson...
Everybody have a good weekend.
Thank youStevens Miller wrote: . . . Everybody have a good weekend.
Stevens
Stevens Miller wrote:Or, of course, I could just use a language that has an unsigned primitive in the size I get my data to begin with...
"Leadership is nature's way of removing morons from the productive flow" - Dogbert
Articles by Winston can be found here
Lasagna is spaghetti flvored cake. Just like this tiny ad:
Gift giving made easy with the permaculture playing cards
https://coderanch.com/t/777758/Gift-giving-easy-permaculture-playing
|