Hacker News new | past | comments | ask | show | jobs | submit | joshuak's favorites login

> We owe money to the creditors... and what you do with a debt is to you pay it off.

That's not the case. Sometimes, you pay your debt off. Sometimes, you default, and file for bankruptcy. For lenders, it's the cost of doing business. If they don't want to deal with the possibility of bankruptcy, they shouldn't lend out money.

Lenders charge creditors a premium, because of the risk of default. It's as much on them to be careful about who they lend money to, as it is on the creditor to be careful about being able to pay off their debts.


For the last 2.5 years I've been working at DigitalOcean as a remote employee. DO has more than 50% of the staff remote. I think it's important that a large chunk of a company & team be remote, to be successful in the exercise, so that there be a forcing function to use asynchronous communications. It's been really life changing for me.

We have a bunch of style of remotees; work from home, work from coffeeshop, work from coworking spaces and work from a new place every day.

I've tried all of these styles, starting with work from home, then getting super depressive from loneliness and getting a coworking space (DO pays for it), then realizing I didn't use it and instead working from a mix of home, coffeeshop, and random visits I pay to my friends. And now I've been switching to mostly working from the crazyest settings I can think of. I worked from camping spots, from a sailboat, in a national park, on a beach in Asia, and it all works out once you're used to "travelling from anywhere".

I'm having the best time of my life by experimenting with what it really means when your ability to feed is now decoupled from your physical location. I feel like I'm living in a future that maybe more of the people will have the chance to live soon, and that it's my duty to find a "Theory of Working In The Future". My first theorem is "Don't stay home everyday else you shall go crazy".

Also, think about the implications of OneWeb and the constellation that SpaceX has been working on; I'm thinking "what if I could get low latency/high bandwidth internet from the middle of any ocean"? The future looks bright.

[edit]: just realized I'm kind of praising my employer a lot here. My comment isn't meant as recruiting spam, tho I think DO's great to remote folks. Also we're building massive distributed systems everyday and it's fun. So uh... check this out? http://grnh.se/wv3fgo


As someone who has worked at high scale (1,000+ load balanced servers), this is a nice "primer" I'd share with a new(er) engineer, or someone who has not worked in a horizontally scaled environment.

A few things I'll point out in addition to this article:

[1] I've found I greatly prefer databases that handle the resiliency and horizontal scalability natively (or natively in their respective client libraries). DBs natively scaling has been one of the greatest advancements in web technologies during my career, and I'd really recommend taking a look at the technologies like Riak & Cassandra for inspiration.

[2] When scaling horizontally with load balancing, connection pooling becomes something to always pay attention to. If you have 1,000 servers, and 100 database instances, you likely don't want 100,000 active connections. Focusing on things like intra-zone preferences for servers (Server A prefers all DBs in its own rack, "zone", or "region") can be a real headache saver as you scale up.

[3] Capacity planning is always key. What are you trying to plan for? Do you want to survive an entire AWS zone outage? Do you want to be able to survive a region outage? Do you worry about single servers going down, and if something "bigger" happens you'll just eat the downtime? Make sure you and your business stakeholders agree on what "resiliency" looks like to your business. It'll help you balance cost and downtime appropriately.

[4] Remember when you're looking at spare capacity that you take into account the situation where a cache layer suffers an outage. If you have to fall back to the primary source of data, and it potentially is also suffering from degradation of service, what sort of capacity will you have?


I wouldn't mind a smart home so long as e.g light switches have the response time (1ms?)! and reliability (1 million switchings without hiccup?) of a regular switch.

The acceptance level for "problems" switching lights on or off is pretty much zero.

If all the smart functions fail, it has to fall back to a functioning dumb home, like escalators become stairs when broken. Not a non-working home like a broken elevator...


No need to be embarrassed. I think it's useful article, both as a pedagogical "proof of concept" and as a way of evaluating the ability of current compilers to vectorize code. I used a shell script to compile your code with a variety of compilers (gcc-4.8, gcc-4.9, gcc-5, gcc-6, icc-16, icc-17, and clang-4.0) each with a variety of compilation options (-O0, -O1, -O2, -O3, -Ofast, -march=native, -flto/-ipo) to see how they fared on a recent Intel Skylake machine. Across all combinations, I got results that mostly matched what you found.

Some takeaways (highly influenced by my own opinions):

Avoid -O0 for production code. It no longer means "without optimization", and should be understood as "put everything on the stack for easy debugging".

The difference between -O1, -O2, -O3, and -Ofast can be large, but in this case the spread was small (about 10%). Higher numbers usually mean faster performance, but not always. If it really matters, measure. If you have to guess, use -Ofast (which for GCC is approximately -O3 plus -ffast-math).

The flag that makes the biggest positive difference here is "-march=native", which tells the compiler it can use all the instructions supported by the machine you are compiling on. If you are running the software yourself rather than distributing it to others, this should probably be your default. If you don't specify it (or another architecture baseline) your code will run on much older machines, but at the cost of missing many of the vectorization improvements made over the last decade.

Link time optimization (-flto for gcc and clang) or interprocedural optimization (-ipo in icc) lets the compiler optimize across compilation units rather than only within them. Approximately, it makes everything a candidate for inlining, thus giving many more opportunities for optimization. It doesn't make a big difference here (since almost all the work is done in one function) but you should likely be using it more than you are.

Overall, the "portable" version is slower than the "model", which in turn is slower than the "assembly". One read of this is that we don't yet have a "sufficiently clever compiler": the "naive" C version is slower than the "explicitly vectorizable" one, and both are beaten by "naive assembly". This is definitely interesting, and often true, and counters the refrain of "don't bother trying to beat the compiler", but I think it's worth digging deeper and asking why the simplistic assembly is faster than the complicated compiler.

I think the main reason here is that the C code is not sufficiently precise, and doesn't actually reflect the programmer's intent. The compiler fails to vectorize because the code as written isn't safe to vectorize: legally, there could be "aliasing" between the different arrays. The assembly is written to take advantage of the absence of aliasing, but the compiler wasn't given enough information to do this.

Some of this information can be provided by a liberal sprinkling of "restrict" keywords: "void fft_transform(const void * tables, double * restrict real, double * restrict imag)". But I don't think it's fair to put the blame on the programmer for skipping these. Rather than being safe and assuming that the arrays for "real" and "imag" might overlap, in this case it would clearly be more helpful for the compiler to ask the programmer for more guidance rather than silently giving up.

Intel's been doing a fairly good job of giving icc (and icpc) the ability to explain why loops cannot be vectorized. "-qopt-report" and "-guide-vec" give useful hints about what to be changed to allow vectorization. But it still requires significant expertise to figure out what the hints mean, which pragmas to add, and whether it's safe to add them.

In this case, the hand written assembly is faster not because the compiler is generating bad code, but because it incorporates the programmer's silent assumptions. It would be nice if compilers were able to give better feedback to the programmer, as a means of making these assumptions (or their absence) more explicit. Do gcc and clang have options to provide this guidance? Are there outside tools that can?

compilation script: https://gist.github.com/nkurz/ff4f6a495428c5c0eaffb3521ad843...

portable results: https://gist.github.com/nkurz/a44d57538d4530362951beb1ea2c4c...

model results: https://gist.github.com/nkurz/2f362185b7fd42889b8bb533ced5f7...

assembly results: https://gist.github.com/nkurz/6e797e8b635931d2a0e4f32af6a12d...


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: