Originally posted by kylew77
View Post
Announcement
Collapse
No announcement yet.
Richard Stallman Announces GNU C Language Reference Manual
Collapse
X
-
Originally posted by coder View PostNot sure I agree that assembly is necessary for learning "efficient programming". C is good enough, for that.
Yeah, the main thing assembly language programming teaches you is how much even a C compiler does for you. Register allocation is a huge headache, if you have to do it by hand. Something with lots of general purpose registers, like ARM, should be good for dabbling. That way, you shouldn't have to redo register allocation every time you make a little code change.
​When I was writing SSE code, I used the C intrinsics but I'd check the compiler output, to make sure it wasn't generating lots of extraneous instructions. I did find a few surprises, that way! In the end, I got reasonably close to the efficiency of hand-coded assembly, if not better, and with a lot fewer headaches.
Comment
-
Originally posted by kylew77 View Postthrowing assignment like x = 5; and conditions, and basic scanf and printf functions and preprocessor directives all into week 1 is way too much in my opinion!
Originally posted by kylew77 View PostWhat haunts me to this day is we had a woman take the class 3 times and try her hardest and not pass each time and she had to have the class for her engineering degree. She was in mechanical or civil or something like that, someone unlikely to ever need to code in C, but the university insisted that she learn to code in C.
You'd wish that someone could find additional resources before taking a class the second or 3rd time, but again I don't know her circumstances. If nothing else, there have got to be some good Youtube tutorials about this stuff.
Originally posted by kylew77 View PostThis is all ancient history now 2016 and 2017.
- Likes 1
Comment
-
Originally posted by DavidBrown View PostLeak a semaphore, mutex or a file handle, or other kinds of resource, and you could be in far more trouble. So when learning programming, learn to take care of your resources, and then memory management is peanuts
Comment
-
Originally posted by DavidBrown View PostI have seen many people who have programmed in C for a long time, who have no clue as to what happens underneath. You can easily write C code that works correctly, without learning how to get efficient results - especially if you ever work with different classes of processor. I have seen people write "x * 0.5" to divide an integer by 2, and then wonder why their program is so slow on an 8-bit microcontroller.
One of the first tricks I learned to make my MS Quick BASIC programs go faster was to dimension my variables as ints.
Originally posted by DavidBrown View PostEqually, I have seen people who do have some understanding about what is going on underneath, but have no understanding of compilers, write "(x << 2) + x" and claim it is faster than "x * 5". (If that happens to be the fastest way to implement multiply by 5 on the particular target, it's the compiler's job to generate that.)
Originally posted by DavidBrown View PostA major criticism of ARM is that it doesn't have that many general-purpose registers - only 12 (for 32-bit ARM).
Originally posted by DavidBrown View PostKeeping track of what data is in registers,
Originally posted by DavidBrown View PostUsing intrinsics can have its advantages and disadvantages. You need to be very careful about how the compiler can re-arrange code - this can lead to better pipelining and scheduling, but can also lead to trouble if the programmer expects the resulting assembly to match the source code directly. Getting such code right, efficient, and suitable for different processors in the same family is a fine art!
Oh, and restricted pointers. Anyone doing code optimization in C or C++ ought to understand them and when to use them. Although C++ doesn't officially support them, every C++ compiler supports them as a nonstandard extension, because they're that important.
I think the reason the C++ standards committee doesn't like them is that they will break your code, if used improperly. Worse, the breakage is likely dependent on compiler optimization level, which makes usage errors even harder to debug.Last edited by coder; 08 September 2022, 10:52 AM.
- Likes 1
Comment
-
Originally posted by coder View PostUh, but the GC languages I know all use objects to manage those other resources, as well. So, garbage collection saves you in those areas, unless you keep an explicit reference to an object, longer than you should.
There might be an object for managing the lock, and the memory for that can be garbage collected. But not the lock.
So when you use a garbage collected language like Python, you use a "with" statement to control the lock - you don't rely on garbage collection.
(Note that C++ style RAII is entirely different. There you have precise semantics about the order and time when objects are destructed, and therefore when the lock gets released.)
- Likes 2
Comment
-
Originally posted by DavidBrown View Postyou want your locks to be taken when you ask for them, in the order you ask for them, and to be released when you ask to release them, in the order you ask (which is almost always the reverse order from acquisition). You don't say "release this lock some time, whenever it suits and you have nothing else to do".
Yes, you will typically want to make explicit unlock calls, to reduce latency. I would still want GC to release a mutex as a fallback, in case I forget.
Third, unlock order doesn't matter the same way that locking order does. If you lock in the wrong order, a deadlock can occur. However, unlocking in the wrong order won't cause a deadlock, as long as all of the locks are eventually released.
Comment
-
Originally posted by coder View PostFirst, that's a little bit of cherry-picking from what you originally said. Your original list was rather open-ended, and now you're just singling out locks. For instance, there are many cases where file handles are merely used to manage a resource, rather than mapping to an actual file that you want to close promptly because someone else might open it. Take, for instance, a poll fd or eventfd.
Yes, you will typically want to make explicit unlock calls, to reduce latency. I would still want GC to release a mutex as a fallback, in case I forget.
Third, unlock order doesn't matter the same way that locking order does. If you lock in the wrong order, a deadlock can occur. However, unlocking in the wrong order won't cause a deadlock, as long as all of the locks are eventually released.
There's no advantage to garbage collection for that kind of thing, and clear and obvious disadvantages (unlike memory, for which garbage collection can be a definite efficiency win as well as being very convenient). That's why with modern garbage collected languages, you generally do not use garbage collection for handling resources other than memory - you use try/finally blocks in Java, "with" statements in Python, "using" statements in C#, etc.
If I saw in a code review that someone had releasing a mutex in garbage collection "as a fallback", I'd reject the code. There is no way to test that synchronisation directives are correct in your code - it could all work by coincidence each time you test it, and testing is non-deterministic. You have to get it right in the code - and be absolutely sure that it is correct. Such a "fallback" says you are not sure - so go back and re-write or re-structure the code until you are sure, and it's obvious that you are sure because it is obvious that the synchronisations are correct. There are situations where "defensive" programming is good, or where it is useful to "minimise" the damage that might result from bugs - this is not one of them.
(You are, of course, correct that the order of release of locks rarely matters.)
Comment
-
Originally posted by DavidBrown View PostThere's no advantage to garbage collection for that kind of thing, and clear and obvious disadvantages
Originally posted by DavidBrown View PostThat's why with modern garbage collected languages, you generally do not use garbage collection for handling resources other than memory - you use try/finally blocks in Java, "with" statements in Python, "using" statements in C#, etc.
Originally posted by DavidBrown View PostIf I saw in a code review that someone had releasing a mutex in garbage collection "as a fallback", I'd reject the code.
What about file descriptors, where the program leaks more and more fds, the longer it runs, until operations utilizing file descriptors just randomly start failing? Is that a preferable outcome?
I think you're being too idealistic.
Comment
-
Originally posted by Developer12 View PostI wouldn't expect him to ever include it, but I still laughed at the exclusion of rust.
On the one hand, it can do any job C can but doesn't allow those mistakes. It even has pointers (of a sort).
At the same time, GNU will stick to what it has until the project is dead. They'll never re-implement things.
Nevermind ideological differences like the propensity towards permissive licences in the rust community.You do not have permission to view this gallery.
This gallery has 1 photos.
- Likes 1
Comment
Comment