Coding: Fleeting Thoughts

A place to discuss the implementation and style of computer programs.

Moderators: phlip, Moderators General, Prelates

BedderDanu
Posts: 39
Joined: Tue Jan 14, 2014 6:18 am UTC

Re: Coding: Fleeting Thoughts

Postby BedderDanu » Tue Jan 14, 2014 6:37 am UTC

Thesh wrote:Why does this matter?

Code: Select all

SELECT 1 WHERE 1 NOT IN (NULL)


That's why.


I know it's a few days old, but wouldn't

Code: Select all

SELECT 1 WHERE 1 IS DISTINCT FROM NULL

get you what you want? IS DISTINCT FROM and IS NOT DISTINCT FROM treat null as a value

Code: Select all

a    | b       | operation   | result
_____________________________________
null | null    | a IDF b     | false
null | null    | a INDS b    | true
null | value   | a IDF b     | true
null | value   | a INDF b    | false

User avatar
Diadem
Posts: 5654
Joined: Wed Jun 11, 2008 11:03 am UTC
Location: The Netherlands

Re: Coding: Fleeting Thoughts

Postby Diadem » Tue Jan 14, 2014 8:40 am UTC

I downloaded it from www.threadbuildingblocks.org, which is the official site I think. The dowload is called "tbb42_20131118oss_win". I took a look at the header file, and there are two different atomics defined there, one with and one without fetch_and_add. As far as I can tell the latter should only be used for atomic<void>. But clearly it isn't. I can only assume that's a bug in tbb, though I'm not sure exactly under which circumstances it occurs.

Anyway, these are my results so far:

Code: Select all

Short Algoritm, calculation of pi (100000000 steps):
Using Serial: pi = 3.141592653590426,   905 ms
Using OpenMP: pi = 3.141592653589683,   453 ms
Using    PPL: pi = 3.141592653589739,  1123 ms
Using    TBB: pi = 3.141592653590731,  7504 ms
Long Algorithm: calculation of sum of primes (100000 steps):
Using Serial: Sum of Primes = 454396537,  2589 ms
Using OpenMP: Sum of Primes = 454396537,  1498 ms
Using    PPL: Sum of Primes = 454396537,  1310 ms
Using    TBB: Sum of Primes = 454396537,  1295 ms


The 'short algorithm' is a single term in a series for pi, which is done in parallel for a lot of terms. The 'long algorithm' is a, purposefully extremely inefficient, test whether a number is prime. Overhead should be pretty low on this long algorithm. And indeed all parallel packages score well. TBB and PPL are I think very similar in architecture, so no surprise they score the same. I'm a bit surprised openMP is slower though.

openMP wins in overhead, but that could be insufficient skill on my part. Certainly the terrible terrible performance of TBB is due to not having atomics. PPL should also score better if you use a newer version - I only got Visual Studio 2010, and that misses a few PPL constructs that should simplify things. I also use the default scheduler for both, which probably is not ideal for such a short algorithm.

In the end, all three choices are probably workable. Which means I have to look at them in more detail to make a choice.
It's one of those irregular verbs, isn't it? I have an independent mind, you are an eccentric, he is round the twist
- Bernard Woolley in Yes, Prime Minister

User avatar
Yakk
Poster with most posts but no title.
Posts: 11128
Joined: Sat Jan 27, 2007 7:27 pm UTC
Location: E pur si muove

Re: Coding: Fleeting Thoughts

Postby Yakk » Tue Jan 14, 2014 12:56 pm UTC

What compiler and version? Maybe it screws it up.

What is the atomic type you are using (is it actually int?)?

Tried std::atomic?

An advantage if ppl is apl simularity. Which opens up graphics cards.
One of the painful things about our time is that those who feel certainty are stupid, and those with any imagination and understanding are filled with doubt and indecision - BR

Last edited by JHVH on Fri Oct 23, 4004 BCE 6:17 pm, edited 6 times in total.

User avatar
Diadem
Posts: 5654
Joined: Wed Jun 11, 2008 11:03 am UTC
Location: The Netherlands

Re: Coding: Fleeting Thoughts

Postby Diadem » Tue Jan 14, 2014 2:48 pm UTC

I'm using Visual Studio 2010. It doesn't support std::atomic. It's c++11 support is shaky at best. And yes, it was atomic<int>.

I now added boost::threads to my comparison. It's the most low level implementation, with thread creation done manually. Unsurprisingly it's rather fast, though not as fast as PPL or TBB for the long algorithm. Probably due to them having work stealing. Strangely enough it gets faster with more threads, and with just 2 threads it's in fact exactly as fast as the serial case - meaning it's not doing any parallelization. Anybody know why that is?

Anyway, the bottomline is that I still don't know which framework is the best. PPL has the friendliest syntax, but it's rather limited without upgrading to VS2013. Plus it means saying goodbye to any thought of ever making a non-windows version of the product. openMP seems a good choice, with a relatively friendly syntax and broad portability. However it also seems to be the slowest of the bunch, at least for my limited test. Plus I think openMP is more designed for task parallelism than data parallelism (but I could be wrong). PPL has good performance and power, if I can get those weird kinks straightened out, but I just don't like the way it complicates things. And using manual threading (with boost or the c++ stl) just seems too pedestrian.

Why is there no software package that has everything I want in exactly the way I want it :)
It's one of those irregular verbs, isn't it? I have an independent mind, you are an eccentric, he is round the twist
- Bernard Woolley in Yes, Prime Minister

User avatar
Yakk
Poster with most posts but no title.
Posts: 11128
Joined: Sat Jan 27, 2007 7:27 pm UTC
Location: E pur si muove

Re: Coding: Fleeting Thoughts

Postby Yakk » Tue Jan 14, 2014 2:53 pm UTC

I said APL -- I meant AMP.

AMP has been ported to a branch of clang, and AMP is basically PPL on steroids (the ability to write graphics card code in C++ and toss it at PPL-like interfaces):

http://isocpp.org/blog/2013/11/amp
One of the painful things about our time is that those who feel certainty are stupid, and those with any imagination and understanding are filled with doubt and indecision - BR

Last edited by JHVH on Fri Oct 23, 4004 BCE 6:17 pm, edited 6 times in total.

User avatar
Diadem
Posts: 5654
Joined: Wed Jun 11, 2008 11:03 am UTC
Location: The Netherlands

Re: Coding: Fleeting Thoughts

Postby Diadem » Tue Jan 14, 2014 3:36 pm UTC

is AMP widely used? I've heard of it, and it sounds awesome, but I can't find too much about it online, leading me to believe it isn't very popular.
It's one of those irregular verbs, isn't it? I have an independent mind, you are an eccentric, he is round the twist
- Bernard Woolley in Yes, Prime Minister

User avatar
Yakk
Poster with most posts but no title.
Posts: 11128
Joined: Sat Jan 27, 2007 7:27 pm UTC
Location: E pur si muove

Re: Coding: Fleeting Thoughts

Postby Yakk » Tue Jan 14, 2014 3:44 pm UTC

Not that I know of: But it looks promising. And microsoft is pushing for standardization of it.
One of the painful things about our time is that those who feel certainty are stupid, and those with any imagination and understanding are filled with doubt and indecision - BR

Last edited by JHVH on Fri Oct 23, 4004 BCE 6:17 pm, edited 6 times in total.

User avatar
Diadem
Posts: 5654
Joined: Wed Jun 11, 2008 11:03 am UTC
Location: The Netherlands

Re: Coding: Fleeting Thoughts

Postby Diadem » Tue Jan 14, 2014 3:58 pm UTC

We need some standards. Parallel computing is the future, but the current landscape is still rather a mess. And most implementations are way too low level, forcing you to think about threads and race conditions and stuff like that. Ideally, I only want to think about algorithms, the rest should be done by my compiler.

Of course C++ isn't exactly the best language for that. Still, I have hopes.
It's one of those irregular verbs, isn't it? I have an independent mind, you are an eccentric, he is round the twist
- Bernard Woolley in Yes, Prime Minister

korona
Posts: 495
Joined: Sun Jul 04, 2010 8:40 pm UTC

Re: Coding: Fleeting Thoughts

Postby korona » Tue Jan 14, 2014 4:32 pm UTC

Parallel computing has been around for more than 25 years and the most commonly used standard are OpenMP for shared memory and MPI for distributed systems.

I don't think there hasn't been enough work on libraries for parallel computing. I think that parallel computing is inherently difficult.

The only viable strategy to avoid race conditions is to make communication explicit i.e. communicate via some message / pipe / event interface and avoid the use of mutable shared memory. This has the additional advantage of using only a minimal number of locks, atomic instructions and cache invalidations and is easy to port to distributed environments. However it can be slower than an optimized implementation build on low level primitives in certain scenarios.

EDIT: A better approach to compare parallel performance would be to parallelize the "map"-part of your program (i.e. the computation of primes) and do the "reduce"-part of your program (i.e. counting them) sequentially or do it using a parallel tree-based approach.

EvanED
Posts: 4331
Joined: Mon Aug 07, 2006 6:28 am UTC
Location: Madison, WI
Contact:

Re: Coding: Fleeting Thoughts

Postby EvanED » Tue Jan 14, 2014 7:11 pm UTC

Diadem wrote:Certainly the terrible terrible performance of TBB is due to not having atomics.
...which means your comparison is bad. What happens if you use parallel_for with, say, boost::atomic? You get the higher-level task-based API that comes with TBB but are giving it a fair test.

Or you could figure out why atomics aren't working for you, because Yakk's right -- from inspection they are there and should be working. I missed some macro expansions before, and there are versions applicable to more than pointers. tbb/atomic.h contains

Code: Select all

__TBB_DECL_ATOMIC(long)
__TBB_DECL_ATOMIC(unsigned long)
__TBB_DECL_ATOMIC(unsigned)
__TBB_DECL_ATOMIC(int)
...

each of which expands to something like

Code: Select all

template<> struct atomic<T>: internal::atomic_impl_with_arithmetic<T,T,char> {
    ....
};

where internal::atomic_impl_with_arithmetic contains both fetch_and_add and operator+=.

What compiler are you using?

korona wrote:A better approach to compare parallel performance would be to parallelize the "map"-part of your program (i.e. the computation of primes) and do the "reduce"-part of your program (i.e. counting them) sequentially or do it using a parallel tree-based approach.
That's better if it works. Not every problem fits into that sort of framework. Heck, in a theoretical sense not every problem can be efficiently paralleled.

korona
Posts: 495
Joined: Sun Jul 04, 2010 8:40 pm UTC

Re: Coding: Fleeting Thoughts

Postby korona » Wed Jan 15, 2014 8:45 am UTC

EvanED wrote:
korona wrote:A better approach to compare parallel performance would be to parallelize the "map"-part of your program (i.e. the computation of primes) and do the "reduce"-part of your program (i.e. counting them) sequentially or do it using a parallel tree-based approach.
That's better if it works. Not every problem fits into that sort of framework. Heck, in a theoretical sense not every problem can be efficiently paralleled.

Unless P = NC :D. Yeah, not every problem fits into that framework but both problems Diadem posted do.

User avatar
You, sir, name?
Posts: 6983
Joined: Sun Apr 22, 2007 10:07 am UTC
Location: Chako Paul City
Contact:

Re: Coding: Fleeting Thoughts

Postby You, sir, name? » Sat Jan 18, 2014 12:44 am UTC

Does anyone else get that thing where the BAs are all "Let's implement feature X", and they draw up specifications and everything is nice, and you develop it, and then 3 days before release they're all "X? Oh, the customers wanted that renamed that to Y"... and now all your code is located in classes called "com.company.project.X.moduleDoingX.SomeXFroobnikThatDoesX", and you can sort of make it work in the user-facing stuff, but all the internals refer X in a billion places and you're never going to change it to Y.
I edit my posts a lot and sometimes the words wrong order words appear in sentences get messed up.

User avatar
tastelikecoke
Posts: 1208
Joined: Mon Feb 01, 2010 7:58 am UTC
Location: Antipode of Brazil
Contact:

Re: Coding: Fleeting Thoughts

Postby tastelikecoke » Sat Jan 18, 2014 12:03 pm UTC

So after some tinkering with C++ programs, I encountered a problem in integer overflow errors. So I searched for stackoverflow articles how to catch overflows and apparently there is no simple "try catch" way for it. I thought "Wow, I wish it was like Java".

I have usually denounced Java as slow trudging language with wordy data structures. Now I don't know what to believe in. And I also had complaints in python and its im/mutability rules. Is there truly no such thing as an ideal language for me? </3

User avatar
Xenomortis
Not actually a special flower.
Posts: 1448
Joined: Thu Oct 11, 2012 8:47 am UTC

Re: Coding: Fleeting Thoughts

Postby Xenomortis » Sat Jan 18, 2014 12:44 pm UTC

Yeah, you have to check for it yourself. Of course, it doesn't help if it's a signed integer that overflows, since I think the behaviour is only defined for unsigned integers.

tastelikecoke wrote:I have usually denounced Java as slow trudging language with wordy data structures. Now I don't know what to believe in.

Well I don't think the flurry of colons and angle brackets that form C++ data structures are particularly friendly.
I mean "std::vector< std::map< char, std::unordered_set< int > > >" isn't exactly pretty.
And of course that'll throw compiler errors unless you perform the necessary dance.

But just because you didn't like C++ doesn't mean you've been wrong about Java. I'll leave that to others to discuss.
Image

korona
Posts: 495
Joined: Sun Jul 04, 2010 8:40 pm UTC

Re: Coding: Fleeting Thoughts

Postby korona » Sat Jan 18, 2014 1:01 pm UTC

Java also doesn't handle integer overflow/underflow. That would require too many useless runtime checks. Java is not "safer" than C in this respect.

User avatar
tastelikecoke
Posts: 1208
Joined: Mon Feb 01, 2010 7:58 am UTC
Location: Antipode of Brazil
Contact:

Re: Coding: Fleeting Thoughts

Postby tastelikecoke » Sat Jan 18, 2014 1:08 pm UTC

Xenomortis wrote:Well I don't think the flurry of colons and angle brackets that form C++ data structures are particularly friendly.
I mean "std::vector< std::map< char, std::unordered_set< int > > >" isn't exactly pretty.

But it is pretty! I like nesting angle brackets, and I prefer my data structures to be free of referencing.
Look:

Code: Select all

std::vector<std::map<std::string,int> >::iterator it = v.begin();
It's so cuuute!
Xenomortis wrote:And of course that'll throw compiler errors unless you perform the necessary dance.

I can dance all day!

If only I had a language as low-high-level as C++ and as easy to debug as Java[citation needed], maybe my life would be better and happier.

Ubik
Posts: 1016
Joined: Thu Oct 18, 2007 3:43 pm UTC

Re: Coding: Fleeting Thoughts

Postby Ubik » Sat Jan 18, 2014 2:45 pm UTC

I wanted to take a look into how the C++ standard library that comes with gcc does shared_ptr. It's not exactly obvious code to me. I guess I could retry after applying some code formatting program to get past the confusing layout. Not that it will probably be all that clear after that either.

More specifically, I'm interested to find out how enable_shared_from_this works. My first guess was that it turns the data structure into something similar that make_shared does, so that the reference counter, or whatever structure is being used, comes along with the object itself. Though now that I'm typing this, I realized the shared_ptr code could probably just detect the presence of enable_shared_from_this and set the weak_ptr inside of it.

User avatar
Thesh
Made to Fuck Dinosaurs
Posts: 6577
Joined: Tue Jan 12, 2010 1:55 am UTC
Location: Colorado

Re: Coding: Fleeting Thoughts

Postby Thesh » Sat Jan 18, 2014 4:23 pm UTC

korona wrote:Java also doesn't handle integer overflow/underflow. That would require too many useless runtime checks. Java is not "safer" than C in this respect.

It shouldn't do it at all, as many things rely on integer overflow (usually unsigned). However, there is an x86 status flag that gets set when an addition operation overflows and I could see a language construct like overflows(a + b) to explicitly say "add a and b and return an enum indicating whether the operations overflows."
Summum ius, summa iniuria.

korona
Posts: 495
Joined: Sun Jul 04, 2010 8:40 pm UTC

Re: Coding: Fleeting Thoughts

Postby korona » Sat Jan 18, 2014 5:13 pm UTC

Hack: Use inline assembly and the "seto" or "jo" instruction (yeah, they have strange mnemonics :D) to accomplish that in C++. Fall back to manual checking if not on a x86 platform.

User avatar
Thesh
Made to Fuck Dinosaurs
Posts: 6577
Joined: Tue Jan 12, 2010 1:55 am UTC
Location: Colorado

Re: Coding: Fleeting Thoughts

Postby Thesh » Sat Jan 18, 2014 5:55 pm UTC

On a tangentially related question, I wonder for people here what would prefer for data types in a statically typed language:

a) All integer types signed by default with a prefix to make them unsigned
b) All integer types unsigned by default, with a prefix to make them signed
c) 8-bit integer unsigned by default with a prefix to make it signed, all other integer types signed by default with a prefix to make them unsigned

I'm leaning towards b. It seems to me like 90% of the time I don't need a negativable (it's a word, google returns results) number. Granted, in most of these cases I would not notice a difference between signed and unsigned anyway. Signed integers just seem to be more complicated to me (although it's probably irrelevant), and I think the simplest choice should be the default choice.
Summum ius, summa iniuria.

EvanED
Posts: 4331
Joined: Mon Aug 07, 2006 6:28 am UTC
Location: Madison, WI
Contact:

Re: Coding: Fleeting Thoughts

Postby EvanED » Sat Jan 18, 2014 6:07 pm UTC

Xenomortis wrote:Well I don't think the flurry of colons and angle brackets that form C++ data structures are particularly friendly.
I mean "std::vector< std::map< char, std::unordered_set< int > > >" isn't exactly pretty.
And of course that'll throw compiler errors unless you perform the necessary dance.
C++ gives you typedefs, which help a lot with that.

Thesh wrote:It shouldn't do it at all, as many things rely on integer overflow (usually unsigned).
I strongly disagree. Overflows can and have lead to all sorts of obnoxious problems and security vulnerabilities. If you want overflow, you should ask for it.

Thesh wrote:On a tangentially related question, I wonder for people here what would prefer for data types in a statically typed language:

a) All integer types signed by default with a prefix to make them unsigned
b) All integer types unsigned by default, with a prefix to make them signed
c) 8-bit integer unsigned by default with a prefix to make it signed, all other integer types signed by default with a prefix to make them unsigned

I'm leaning towards b. It seems to me like 90% of the time I don't need a negativable (it's a word, google returns results) number. Granted, in most of these cases I would not notice a difference between signed and unsigned anyway. Signed integers just seem to be more complicated to me (although it's probably irrelevant), and I think the simplest choice should be the default choice.
I use negative numbers a ton, and would strongly prefer (a). It's interesting, because I consider the situation reversed... I almost consider unsigned numbers to be more trouble than they're worth. :-)

User avatar
Yakk
Poster with most posts but no title.
Posts: 11128
Joined: Sat Jan 27, 2007 7:27 pm UTC
Location: E pur si muove

Re: Coding: Fleeting Thoughts

Postby Yakk » Sat Jan 18, 2014 6:43 pm UTC

tastelikecoke wrote:So after some tinkering with C++ programs, I encountered a problem in integer overflow errors. So I searched for stackoverflow articles how to catch overflows and apparently there is no simple "try catch" way for it. I thought "Wow, I wish it was like Java".

Write your own checking integer type. Bit of boilerplate.

Probably easier to just do away with overflow however.

I do not want to pay for your checks. In C++ you only pay for what you use.
I have usually denounced Java as slow trudging language with wordy data structures.

And yet you want branches and checks and everythimg around every `int` operation. Do you think that comes for free?
Last edited by Yakk on Sat Jan 18, 2014 9:16 pm UTC, edited 1 time in total.
One of the painful things about our time is that those who feel certainty are stupid, and those with any imagination and understanding are filled with doubt and indecision - BR

Last edited by JHVH on Fri Oct 23, 4004 BCE 6:17 pm, edited 6 times in total.

User avatar
Thesh
Made to Fuck Dinosaurs
Posts: 6577
Joined: Tue Jan 12, 2010 1:55 am UTC
Location: Colorado

Re: Coding: Fleeting Thoughts

Postby Thesh » Sat Jan 18, 2014 6:49 pm UTC

EvanED wrote:I strongly disagree. Overflows can and have lead to all sorts of obnoxious problems and security vulnerabilities. If you want overflow, you should ask for it.


It was a bad argument on my side, since most of the time you don't expect overflow. However, it's cost vs benefit, and I don't think the benefit is worth the cost.


EvanED wrote:It's interesting, because I consider the situation reversed... I almost consider unsigned numbers to be more trouble than they're worth. :-)


I've been playing around a lot with cryptography lately, and a lot of stuff relies on addition modulo 2^n, so I'm probably looking with a very biased perspective. Of course, in actuality, there is normally no multiplication or comparisons, just addition and subtraction, I could probably replace the unsigned ints in my code with signed ints and not see a difference at all. Most of the time, when I'm using negatives, it's finance related and I'm using decimal data types. When I am using integers (apart from cryptographic stuff), it's usually counters or memory related stuff, where I would not expect a negative.
Summum ius, summa iniuria.

User avatar
jaap
Posts: 2094
Joined: Fri Jul 06, 2007 7:06 am UTC
Contact:

Re: Coding: Fleeting Thoughts

Postby jaap » Sat Jan 18, 2014 9:43 pm UTC

Thesh wrote:
EvanED wrote:I strongly disagree. Overflows can and have lead to all sorts of obnoxious problems and security vulnerabilities. If you want overflow, you should ask for it.

It was a bad argument on my side, since most of the time you don't expect overflow. However, it's cost vs benefit, and I don't think the benefit is worth the cost.
EvanED wrote:It's interesting, because I consider the situation reversed... I almost consider unsigned numbers to be more trouble than they're worth. :-)

I've been playing around a lot with cryptography lately, and a lot of stuff relies on addition modulo 2^n, so I'm probably looking with a very biased perspective. Of course, in actuality, there is normally no multiplication or comparisons, just addition and subtraction, I could probably replace the unsigned ints in my code with signed ints and not see a difference at all. Most of the time, when I'm using negatives, it's finance related and I'm using decimal data types. When I am using integers (apart from cryptographic stuff), it's usually counters or memory related stuff, where I would not expect a negative.

One irritating situation that occurs with unsigned integers is when you have a for loop with a decreasing index, and you want to have it count all the way down to zero.
With signed integers, you would just use the standard for loop:

Code: Select all

for( int ix=n-1; ix>=0; --ix) { ... }

This does not work with an unsigned ix variable - it becomes an infinite loop as ix underflows from 0 to UINT_MAX. Instead, you would probably have to use something like this:

Code: Select all

for( unsigned ix=n; ix--; ) { ... }

I find this less readable, as it is far too easy to make fencepost errors.

Note that ix will still underflow even in this working version, so you would not want that to raise an error.

User avatar
Thesh
Made to Fuck Dinosaurs
Posts: 6577
Joined: Tue Jan 12, 2010 1:55 am UTC
Location: Colorado

Re: Coding: Fleeting Thoughts

Postby Thesh » Sat Jan 18, 2014 10:43 pm UTC

That's why you do this:

Code: Select all

int a[10] = 0;
int i = 10;
do {
    i--;
    //do stuff with array
}
while (i>0);
Summum ius, summa iniuria.

User avatar
Diadem
Posts: 5654
Joined: Wed Jun 11, 2008 11:03 am UTC
Location: The Netherlands

Re: Coding: Fleeting Thoughts

Postby Diadem » Sun Jan 19, 2014 1:00 am UTC

Using a do-while to make a for-loop? Ugly!
It's one of those irregular verbs, isn't it? I have an independent mind, you are an eccentric, he is round the twist
- Bernard Woolley in Yes, Prime Minister

User avatar
Thesh
Made to Fuck Dinosaurs
Posts: 6577
Joined: Tue Jan 12, 2010 1:55 am UTC
Location: Colorado

Re: Coding: Fleeting Thoughts

Postby Thesh » Sun Jan 19, 2014 1:18 am UTC

Diadem wrote:Using a do-while to make a for-loop? Ugly!

Counting down is always ugly. "for (i=length-1;" - shoot me now.

Even better:

Code: Select all

uint64_t i = 0;
goto entry;
do {
    i++;
    entry:
    //do stuff
} while (i != UINT64_MAX);
Summum ius, summa iniuria.

mr-mitch
Posts: 477
Joined: Sun Jul 05, 2009 6:56 pm UTC

Re: Coding: Fleeting Thoughts

Postby mr-mitch » Sun Jan 19, 2014 1:32 am UTC

jaap wrote:One irritating situation that occurs with unsigned integers is when you have a for loop with a decreasing index, and you want to have it count all the way down to zero.
With signed integers, you would just use the standard for loop:

Code: Select all

for( int ix=n-1; ix>=0; --ix) { ... }

This does not work with an unsigned ix variable - it becomes an infinite loop as ix underflows from 0 to UINT_MAX. Instead, you would probably have to use something like this:

Code: Select all

for( unsigned ix=n; ix--; ) { ... }

I find this less readable, as it is far too easy to make fencepost errors.

Note that ix will still underflow even in this working version, so you would not want that to raise an error.


But that's why I got into the habit of writing ix < n.

It makes things quite interesting. If you're iterating forward or backward, the condition is still the same.

Code: Select all

for (unsigned int i = 0; i < n; ++i) { ... }
for (unsigned int i = n-1; i < n; --i) { ... }

User avatar
Thesh
Made to Fuck Dinosaurs
Posts: 6577
Joined: Tue Jan 12, 2010 1:55 am UTC
Location: Colorado

Re: Coding: Fleeting Thoughts

Postby Thesh » Sun Jan 19, 2014 1:35 am UTC

One other problem is what do you do if your parameter is a size_t (and if it's a length, it *should* be)? That's guaranteed to be unsigned, and mixing signed and unsigned is bad.
Summum ius, summa iniuria.

User avatar
phlip
Restorer of Worlds
Posts: 7572
Joined: Sat Sep 23, 2006 3:56 am UTC
Location: Australia
Contact:

Re: Coding: Fleeting Thoughts

Postby phlip » Sun Jan 19, 2014 2:47 am UTC

Of course, there's always this idiom:

Code: Select all

size_t i = length;
while (i --> 0)
{
  // code
}
(note: please don't actually do this in real code...)

Code: Select all

enum ಠ_ಠ {°□°╰=1, °Д°╰, ಠ益ಠ╰};
void ┻━┻︵​╰(ಠ_ಠ ⚠) {exit((int)⚠);}
[he/him/his]

User avatar
PM 2Ring
Posts: 3713
Joined: Mon Jan 26, 2009 3:19 pm UTC
Location: Sydney, Australia

Re: Coding: Fleeting Thoughts

Postby PM 2Ring » Sun Jan 19, 2014 6:14 am UTC

I learned my first assembler language (IBM 360/370) before I knew C existed. I've occasionally been annoyed by C's lack of overflow handling, but I guess Ritchie & co decided that it was too hard to do it portably, and that if anyone really needed it they could revert to assembler. :)

operator[]
Posts: 156
Joined: Mon May 18, 2009 6:11 pm UTC
Location: Stockholm, Sweden

Re: Coding: Fleeting Thoughts

Postby operator[] » Sun Jan 19, 2014 9:34 pm UTC

If you don't care about portability, gcc has a flag -ftrapv for trapping (i.e. crashing, by default) on signed overflow. Performance is about as terrible as you'd expect, but it's lovely for things like Project Euler.

User avatar
tastelikecoke
Posts: 1208
Joined: Mon Feb 01, 2010 7:58 am UTC
Location: Antipode of Brazil
Contact:

Re: Coding: Fleeting Thoughts

Postby tastelikecoke » Mon Jan 20, 2014 1:32 pm UTC

korona wrote:Java also doesn't handle integer overflow/underflow. That would require too many useless runtime checks. Java is not "safer" than C in this respect.

Damn. I wish EEE people had a hardware way of checking overflows. It sounds easy to me :P

But there's always BigInteger in Java :) Note that I'm not really into speed for my current problem. More on correctness, as it's for a programming contest.

User avatar
You, sir, name?
Posts: 6983
Joined: Sun Apr 22, 2007 10:07 am UTC
Location: Chako Paul City
Contact:

Re: Coding: Fleeting Thoughts

Postby You, sir, name? » Mon Jan 20, 2014 3:20 pm UTC

I think the reason the V and C flags (in x86 notation) aren't accessible in higher level languages is because there is no decent abstraction for it.
I edit my posts a lot and sometimes the words wrong order words appear in sentences get messed up.

korona
Posts: 495
Joined: Sun Jul 04, 2010 8:40 pm UTC

Re: Coding: Fleeting Thoughts

Postby korona » Mon Jan 20, 2014 4:22 pm UTC

You, sir, name? wrote:I think the reason the V and C flags (in x86 notation) aren't accessible in higher level languages is because there is no decent abstraction for it.

Well you could define a add-and-throw-exception-on-overflow operator in C++.

lgw
Posts: 437
Joined: Mon Apr 12, 2010 10:52 pm UTC

Re: Coding: Fleeting Thoughts

Postby lgw » Mon Jan 20, 2014 6:20 pm UTC

PM 2Ring wrote:I learned my first assembler language (IBM 360/370) before I knew C existed. I've occasionally been annoyed by C's lack of overflow handling, but I guess Ritchie & co decided that it was too hard to do it portably, and that if anyone really needed it they could revert to assembler. :)


I guess it depends on the sort of "overflow handling" you're looking for. I believe it was Ritchie who explained that C arithmetic operations can't overflow, because they're all defined modulo 2n: MAX_INT + 1 = MIN_INT, because the domain is a ring. :roll:

Still, you might be surprised at how the optimizer might be your friend. Just because there's no abstraction in C (and we don't call C a "high level language" these days :P ) doesn't mean you can't get at the functionality, if you can express it in C in a round-about way. I haven't messed with the carry and overflow flags, but for example for 32-bit ints

Code: Select all

(x << n) | (x >> (32 - n))
will be optimized to a single rotate instruction with modern compilers/platforms. I was once upset about the lack of a rotate abstraction, but really it's just syntax sugar: I can express what I want, and the optimizer will be smart about it, so I can make a macro for clarity if needed.
"In no set of physics laws do you get two cats." - doogly

EvanED
Posts: 4331
Joined: Mon Aug 07, 2006 6:28 am UTC
Location: Madison, WI
Contact:

Re: Coding: Fleeting Thoughts

Postby EvanED » Mon Jan 20, 2014 6:27 pm UTC

lgw wrote:I guess it depends on the sort of "overflow handling" you're looking for. I believe it was Ritchie who explained that C arithmetic operations can't overflow, because they're all defined modulo 2n: MAX_INT + 1 = MIN_INT, because the domain is a ring.
That's true for unsigned numbers, but not for signed ones, so not of MAX_INT+1=MIN_INT; overflow of signed integers is undefined behavior, and compilers will take advantage of that to optimize away conditionals in the right situations. For example, int x = foo(); if(x+1 < x) { ... } can be optimized to int x = foo(); because the only situations in which x+1 < x is true is when undefined behavior happened anyway.

(I'll come back to the unsigned int vs cost question in a few days; I want to run some tests first, and I'm busy at the moment.)

User avatar
Xenomortis
Not actually a special flower.
Posts: 1448
Joined: Thu Oct 11, 2012 8:47 am UTC

Re: Coding: Fleeting Thoughts

Postby Xenomortis » Tue Jan 21, 2014 11:17 pm UTC

So I started looking at the Java code base that I'll soon be working with.
I can't comment on the code, because I found it so hard to parse in Eclipse; something about that editor's defaults made it extraordinarily difficult for me to read.
I don't really know why either, I can read (with only some difficulty) code without any syntax highlighting, in fairly dense format.
But I couldn't read this.

Maybe it's the combination of long class names, no real highlighting beyond Java keywords and the little use of whitespace* beyond indenting made it really hard for me to read.
But I think the font was the real culprit; I found it much easier to read when I quickly opened one of the files in vim, and it didn't highlight much more (although it is light on dark).

I hope simple style changes in Eclipse are sufficient.


*I'm weird in that I like superfluous spaces at times, particularly inside parentheses.
Image

User avatar
Link
Posts: 1404
Joined: Sat Mar 07, 2009 11:33 am UTC
Location: ᘝᓄᘈᖉᐣ
Contact:

Re: Coding: Fleeting Thoughts

Postby Link » Thu Jan 23, 2014 8:59 pm UTC

phlip wrote:Of course, there's always this idiom:

Code: Select all

size_t i = length;
while (i --> 0)
{
  // code
}
(note: please don't actually do this in real code...)

As with several things I've seen in this thread, that's actually quite reasonable in embedded use: such code may compile to something marginally smaller than a safer and more intuitive approach. Atmel even recommends this approach for 8-bit AVR programming.

User avatar
phlip
Restorer of Worlds
Posts: 7572
Joined: Sat Sep 23, 2006 3:56 am UTC
Location: Australia
Contact:

Re: Coding: Fleeting Thoughts

Postby phlip » Thu Jan 23, 2014 10:35 pm UTC

To be clear, "while(n--)" is an idiom I've seen in a number of places, and is fine if you're trying to squeeze out every last instruction (and have a compiler with a less-than-impressive optimiser)... it's specifically when typed it to look like some kind of "arrow operator" that I say "please don't actually do this".

Code: Select all

enum ಠ_ಠ {°□°╰=1, °Д°╰, ಠ益ಠ╰};
void ┻━┻︵​╰(ಠ_ಠ ⚠) {exit((int)⚠);}
[he/him/his]


Return to “Coding”

Who is online

Users browsing this forum: No registered users and 9 guests