I

IT Hare

ithare.com · Personal blog · on HN since 2015

IT Hare is a blog by a game-development veteran on low-level performance, networking, memory allocators and multiplayer game architecture.

What HN saysHN links it for its reference-style posts, such as CPU operation costs and the TCP-versus-UDP debate for games.
80HN people shared it
23linked it in comments
115stories submitted
1.6Kstory points
8 months agolast shared
2015people per year2026

Most-shared posts

  1. 1
    Operation Costs in CPU Clock Cycles
    15 people · 291 points · first shared 2016 · 67 comments on HN
  2. 2
  3. 3
    64 Network DO’s and DON’Ts for Game Engines
    4 people · 20 points · first shared 2015 · 1 comments on HN
  4. 4
  5. 5
    UDP for games – encryption and DDoS protection
    3 people · 104 points · first shared 2016 · 44 comments on HN
  6. 6
  7. 7
  8. 8
    Random Number Generation
    3 people · 8 points · first shared 2016 · 1 comments on HN
  9. 9
    C++: Thoughts on Dealing with Signed/Unsigned Mismatch
    3 people · 6 points · first shared 2018 · discussion on HN
  10. 10
    SQL vs. noSQL for multiplayer online games
    3 people · 4 points · first shared 2016 · discussion on HN
  11. 11
    Password hashing and server relief (2015)
    3 people · 4 points · first shared 2015 · discussion on HN
  12. 12
    IT Hare on Soft.ware
    3 people · 1 points · first shared 2017 · discussion on HN
  13. 13
    C++17 Compiler Bug Hunt
    2 people · 110 points · first shared 2018 · 38 comments on HN
  14. 14
  15. 15
    Password Hashing Why and How
    2 people · 9 points · first shared 2016 · discussion on HN

What HN people wrote when they linked it

andythemoron · 2017-07-25
Julia Evans' blog is one of my favorites! It was a big inspiration for starting my own blog (https://andythemoron.com). I also love High Scalability and Dan Luu's blog which have been mentioned in other comments. I "follow" several which are mostly defunct, but in terms of blogs that still feature active updates: Evan Klitze's blog: lots of topics around Linux, C++, etc. https://eklitzke.org/ Sutter's Mill: lots of "state of the world" for C++, but also context, history, etc. https://herbsutter.com/ IT Hare: C++, game programming http://ithare.com/ The Erlangelist: Erlang/Elixir http://theerlangelist.com/ null program: lots of miscellaneous topics http://nullprogram.com/ Fluent C++: the name speaks for itself http://www.fluentcpp.com/ Another Programmer's Blog: Linux, C, C++, C#, MSSQL https://www.stev.org/
adrianratnapala · 2016-06-21
Addressing those doesn't create bugs, and I'm not sure why it would. Anything that changes behaviour could create bugs. Here is an example signed bar = something_possibly_negative(); if(some_case) { bar = calc_returning_unsigned_where_MSB_is_an_error_flag(); if(bar < 0) return ERROR; } // now bar is valid, whether negative or positive. This is a correct - if dodgy - way to test the MSB. But now if you get a warning about the signed integer not having the full range of the unsigned integer you might "fix" it by changing the first line to long long bar = something_possibly_negative(); Now the signed bar covers the full range of the unsigned calculation - including the garbage in the error case. For more in this vein see: http://ithare.com/best-practices-vs-witch-hunts/
crabmusket · 2022-02-28
I love seeing more options appear on the horizon for doing stateful serverless work. This article[1] provides a little more motivation for the use cases: > For quite a long time (and especially in the webdev world), there exists a perception that to achieve scalability, all our request handlers need to be as stateless as possible. In the world of the all-popular Docker containers, it means that all the app containers need not only to be immutable, but also should be ephemeral ... keeping our request handlers stateless, does NOT really solve the scalability problem; instead it merely pushes it to the database. Though the problems and solutions pointed out in that article don't mean you have to go straight to process-per-X. One solution might be, as mentioned in passing in the OP's launch blog, to keep state in a cache like Redis. If the data fits this approach, it would ease load on the database while allowing each request handler to remain stateless. Durable Objects seem less focused on heavy computation, but I think they're really interesting as points of synchronisation for e.g. collaborative editing. Having all requests go into a _single thread_ seems important. [1]: http://ithare.com/scaling-stateful-objects/
loup-vaillant · 2021-04-03
OP specifically uses that redundancy to prevent use-after-free errors. That redundancy is limited to the handle, and checked at every dereference (in the get_pointer() so you don't forget to check). Desyncs between a handle and the object it points to ought not to be possible at this point. If you remove the redundancy, you have to give up on use-after-free checks. If you want to prevent use-after-free anyway, you need to use a simpler allocation pattern (stack or arena), or fall back to heap allocated pointers (smart pointers in C++, various kind of references in Rust…). But heap allocated pointers were precisely what we were trying to avoid in the first place, most notably because they're not cache friendly, cause memory fragmentation, make leaks harder to detect, and in many cases simply take up much more space than handles (remember, pointers are 8 bytes nowadays). Using handles atomically is probably a consequence of a very bad idea: threads with shared mutable state and locks. As much as humanely possible, you don't want to share any mutable memory to begin with. Send messages instead, it's less error prone, and with current computers, it's often faster as well. See http://ithare.com/ on (re)actors for the gory details. About debugging: some people read code by running it in the default step by step debugger provided by their IDE. I don't understand that way of thinking, so I don't bother catering to it. My code then is optimised for readability without special…
nobugs · 2017-01-08
FWIW: IMO, we should separate CQRS and ES. CQRS is a Good Thing(tm); for a real-world example of it in work on a not-so-shabby system processing 10B+ transactions/year - see http://ithare.com/gradual-oltp-db-development-from-zero-to-10-billion-… . ES, however, is more controversial. If speaking about "pure" ES (i.e. not having any mutable state, and reconstructing current state from input events all the time) - versioning and potential synchronization failures (and synchronized access is a prereq for event sourcing) will kill it very quickly (and I didn't even start speaking about performance, which is going to be a very serious challenge). OTOH, if understanding ES just as an ADDITION to classical mutable-state processing - it can be made very useful. Not only ES will serve as a perfect audit, the duplication of information (once in mutable state and once in input events) will allow such things as regression testing, and fixing data problems caused by bugs, within the DB. BTW - with this model, the latter can be done in a post-factum-fix manner and this, unlike "pure-ES" fixes, is not confusing to the readers who already got and stored previous state of the DB (with "pure" ES, after the fix, all the history can change, invalidating all the data which might have been stored by the third parties, and this is really crazy - imagine if your bank statements would change overnight; with a "ES+mutable" model, bugs still can be identified, and…
deltasevennine · 2022-08-13
>Well I’m not aware of them happening “much less” just that there are less categories of bugs. We will of course rarely have software written with and without GC so it’s not an answer we will find. I would say your very inexperienced then. "Much less" is very obvious. Simply forgetting a delete operator or free in manual allocation leads to a memory leak. It is also proveable. Error surface area is smaller. delete and free don't exist in languages that exclusively use the GC for freeing memory thus you cannot "forget" to use those functions and thus error surface area is smaller, thus it must happen less frequently. >Memory leaks happen very frequently in managed languages e.g., http://ithare.com/java-vs-c-trading-ub-for-semantic-memory-l... It happens but not frequently at all. I'm sorry. If you did manual memory management you would know this.
mirker · 2022-08-10
Well I’m not aware of them happening “much less” just that there are less categories of bugs. We will of course rarely have software written with and without GC so it’s not an answer we will find. Memory leaks happen very frequently in managed languages e.g., http://ithare.com/java-vs-c-trading-ub-for-semantic-memory-leaks-same-…
leath · 2021-09-27
The proof of work idea is cute, but at this stage it's not necessary as profiling seems to show attacks don't get too deep into the netcode before getting dropped. It's hard to know without testing but I'm fairly certain any kind of PoW would cost more to check. This reminds me of a blogpost that is at least fun to read: http://ithare.com/udp-for-games-security-encryption-and-ddos-protectio… Regarding the HTTPS request thing, we already did this for an event and I'm currently getting it set up on all servers. The blog post forgot to mention this one :)
moonchild · 2020-04-27
Note that there are other considerations like absolute allocation speed, like memory fragmentation, which isn't affected by inlining. In the ithare post they link, jemalloc thrashes all other allocators[1] on that front. It would be interesting to see if the newer version of tcmalloc is improved at all in that respect. 1: http://ithare.com/wp-content/uploads/malloc-overhead.png
wahern · 2018-12-07
An indirect function call is ~50 cycles. (http://ithare.com/infographics-operation-costs-in-cpu-clock-cycles/) The entry and exit cost of a syscall is ~150 cycles. (Source: Many Google hits--blogs, papers--show people reciting 150 cycles exactly so I assume there's a singular, primary source for this. Maybe will track down the paper later.) I'd say that's comparable. Many syscalls take much longer, but that's just because syscalls tend to be very abstract interfaces where each call performs costly operations or bookkeeping, especially on shared data structures requiring costly memory barriers. That doesn't mean the syscall interface itself is expensive. Microkernel skeptics stopped arguing syscall overhead a long time ago, and proponents are no longer defensive about it.
60654 · 2018-05-20
Big book being written right now with beta chapters available: http://ithare.com/contents-of-development-and-deployment-of-massively-… Also this site has a nice collection of very widely known blog posts on networking for gamedevs: https://gafferongames.com/
dolftax · 2017-02-27
Do the authentication over TCP and then fallback to UDP for rest of the communication? For encryption, have you considered DTLS? Read more in `Hybrid Implementation` section of http://ithare.com/udp-for-games-security-encryption-and-ddos-protectio…
junke · 2016-06-28
> whether we like it or not, each project effectively creates its own dialect of the language (http://ithare.com/cpp-guidelines-made-to-measure-s-one-size-fits-all/) Each project has its own coding guide and idiosyncrasies. That is not restricted to Lisp. Macros allow you to express some rules in a domain-specific language, not in a separate document or tacit knowledge. This is more manageable than ad-hoc approaches. Abusing macros is definitely bad and can lead to ghetto-languages. Lisp is interactive, call "describe" on whatever you don't understand. Under Emacs, if you encounter a form you don't understand, point to it, "C-c C-d d" and you get the documentation; "M-." and you go to the definition; "C-c M-m" and you call macroexpand.
no-bugs · 2016-06-14
Statistically - yep. See http://ithare.com/facelift-for-no-bugs/ - only 10 out of 160 said that they don't like the cartoons. BTW, there is a "very beta" way to turn them off - use http://ithare.com/visitor-settings/ (NB: "No!" option doesn't really work yet)...
babuskov · 2016-05-30
> Does anyone know who's behind this site/books? http://ithare.com/real-people-behind-the-hare/
Paul_Diraq · 2018-11-25
The best resource in my opinion is still "What every programmer should know about memory." It is now over ten years old but still the most comprehesive and comprehensible post I know about that topic. https://lwn.net/Articles/250967/ AFAIK there have been no major breakthroughts since that time in memory technology (Transactional memory could be one). While modern processors may be build a bit different (e.g. added shared L3 chache) you will have no problem understanding them. There is also this github : https://github.com/Kobzol/hardware-effects for programs which should show such effects. (I haven't used them yet but they may be interesting for you to play with.) IT Hare has published a nice article about those costs including rules of thumb costs. http://ithare.com/infographics-operation-costs-in-cpu-clock-cycles/ Then there are the Agner tables. Giving you latencies and reciprocal throughput for your instructions. https://www.agner.org/optimize/instruction_tables.pdf If you are through these you have to read the intel and AMD optimization guides. (ARM may or may not have something similar.) The paper by Kazushige Goto ("Anatomy of a High Performance Matrix Multiplication") is an example of Cache and TLB considerations in a non-trivial example. http://www.cs.utexas.edu/users/pingali/CS378/2008sp/papers/gotoPaper.p…
emcq · 2017-02-12
Apologies if I'm being too academic here but not all memory bottlenecks or communication bottlenecks are the "Von Neumann Bottleneck". The term was originally focused on both data and program memory being on the other side of a shared bus from the CPU, which meant you could only do one at a time. If you were trying to figure out your next instruction, you wait. If you then need to data, you wait. It wasn't a problem back with slowly executing EDVAC code [0]. Based on this definition most architectures today do not have the Von Neumann Bottleneck as they are not Von Neumann architectures [1, 2, 3]. A slightly looser definition of the Von Neumann Bottleneck refers to the separation between CPU and memory with a single bus. This likely originated because fully Von Neumann architectures are so rare but that the general problem is similar enough to share the name. GPUs dont have this issue because they employ parallelism thru multiple memory ports talking to off chip RAM. TrueNorth also doesn't have this issue because it has 4096 parallel cores with their own localized memory and no off chip memory. There could certainly be other bottlenecks in the system, even with the memory system, but those wouldn't be the Von Neumann Bottleneck [0]. [0] https://en.wikipedia.org/wiki/Von_Neumann_architecture#Von_Neumann_bot… [1] https://news.ycombinator.com/item?id=2645652 [2] http://ithare.com/modified-harvard-architecture-clarifying-confusion/ [3]…
kris-jusiak · 2024-07-22
Hardware branch prediction is very powerful (https://www.intel.com/content/www/us/en/developer/articles/technical/i… but it's also not perfect and costly misdirections may happen (http://ithare.com/infographics-operation-costs-in-cpu-clock-cycles/). Branchless computing (https://www.youtube.com/watch?v=g-WPhYREFjk) is a technique which may help a lot with mitigating the overhead of branching. Alternative way, coming from linux kernel (https://docs.kernel.org/staging/static-keys.html) is to leverage knowledge about branches direction and literally change the instructions via run-time code patching to avoid the potential branching overhead all together. When to go for such extreme solution? When performance really matters: - `and` branches are known at compile-time - `or` branches are not changing often at run-time - `and/or` branches are expensive to compute/require memory access - `and/or` branches are hard to learn by the hardware branch predictor due to their random nature Some examples include logging, tracing, configuration, hot-path, algo, etc. > https://github.com/boost-ext/sb - x86-64/linux/gcc/clang moves the solution to user space (for run-time) as well as to compile-time with C++20. > static_branch - Minimal overhead run-time branch (https://godbolt.org/z/797WeYYGK) / (nop=not taken / jmp=taken) void fun() { // can be inlined/constexpr or not if (sb::static_branch<"semi run-time branch">::get()) { …

Keyboard shortcuts

/Search
j kNext / previous blog
EnterOpen selected blog
vVisit the blog site
fFollow / unfollow
lSwitch grid / list view
dSwitch dark mode
g hHome
g pTop posts
g tTopics
g fFollowing
g lLiked
g yHistory
g qFAQ
EscBack / close