Direct X Raytracing: Further Unification - <AUTHOR> http://darkcephas.blogspot.com/2018/03/direct-x-raytracing-further-unification.html <comment><USER2> Meanwhile, on the Vulkan side: [https://gpuopen.com/announcing-real-time-ray- tracing/](https://gpuopen.com/announcing-real-time-ray-tracing/)

[https://www.youtube.com/watch?v=C9eMciZGN4I](https://www.youtube.com/watch?v=C9eMciZGN4I)

<comment><USER3> Which is only supported on AMD cards.

Given that NVidia has their own API (RTX) , which will be part of Gameworks [0], is collaborating with Microsoft, and is currently requesting papers for Ray Tracing Gems[1], I don't see them bothering with Vulkan support.

[0] - [https://blogs.nvidia.com/blog/2018/03/19/whats-difference- be...](https://blogs.nvidia.com/blog/2018/03/19/whats-difference-between-ray- tracing-rasterization/)

[1] - [https://news.developer.nvidia.com/call-for-papers-real- time-...](https://news.developer.nvidia.com/call-for-papers-real-time-ray- tracing/)

<comment><USER2> Hmm... The video claims that it is open source and supports non-AMD hardware.

[https://www.youtube.com/watch?v=C9eMciZGN4I&t=1m7s](https://www.youtube.com/watch?v=C9eMciZGN4I&t=1m7s)

</comment></comment></comment><comment><USER4> Related and worth reading: [http://aras-p.info/blog/2018/03/21/Random- Thoughts-on-Raytra...](http://aras-p.info/blog/2018/03/21/Random-Thoughts-on- Raytracing/)

<comment><USER5> The black box criticism is fair but to be expected. Early 3D APIs were black boxes, but that had the advantage of allowing IHVs to experiment with different implementations behind the scenes.

Now that things have largely settled down, moving to explicit APIs like Vulkan makes sense.

With hardware acceleration for ray tracing we're only just at the beginning of the development, so having fairly black box APIs makes sense again. Expect that to change eventually once the industry has settled on answers to many of the currently open questions, but it might take a while.

</comment></comment><comment><USER6> can this raytracing pipeline be mixed with rasterization pipeline?

<comment><AUTHOR> Yes. In fact the starting point for the raytracing is the data resulting from rasterizing normal camera view. This technique will allow the expensive raytracing to be used sparingly.

<comment><USER7> What's amusing to me is how closely this resembles the path that some of us went down in film rendering.

If that history is any guide, the hybrid approach here is likely to be a short-lived stop-gap before moving on to full ray tracing for everything. It quickly becomes annoying have to maintain the code paths and the data structures for both rasterization and ray tracing. You have to keep the two carefully in sync (e.g., tessellating to the same level, using the same LoD levels, displacements the same) or you'll get weird artifacts. Even then, numeric precision can still bite you; surface acne and ray trace bias issues are worse than usual when the launch points for your rays are computed by an entirely different rendering technique.

Things get a lot easier when you have just the one codepath and set of data structures. Not to mention that ray tracing for primary visibility tends to be fairly cheap since that's when the rays are the most coherent. A lot of the ray tracing research back in the aughts dealt with efficient acceleration structure traversal and intersection for tightly coherent bundles of rays. People have been ray casting for a long time. I think the bigger deal is that it's only in the past decade where we finally have enough compute power to really start to handle the less coherent secondary rays at real-time rates.

<comment><USER8> "Short" being a relative term though. Your points make sense but there's simply no way raytracing can be as performant as current rasterization techniques in geometry-heavy scenes at a same-or-better quality level, resolution, and framerate until GPUs get substantially more powerful.

<comment><USER9> Thus is entirely the wrong way around: raytracing scales less than linearly with the scene complexity while rasterization is mosyly linear in the number of visible primitives. It is not a simple complexity function in either case, though.

<comment><USER10> > raytracing scales less than linearly with the scene complexity

Not really true, is it? More like O(log n), or linearly to the number of pixels/samples.

<comment><USER9> I meant that in the sense that O(log n) < O(n). But when comparing raytracing to rasterization you have the problem that the complexity depends mostly on different variables for each algorithm.

<comment><USER11> On the other hand, if we assume that every pixel is covered by a constant number of triangles and a typical scene doesn't push more triangles than there are pixels, rasterization suddenly looks a lot more like O(pixels) or O(1) per pixel while ray tracing is still O(log triangles) per pixel accounting only for direct rays.

Then again, it's the constant factors that really matter. A couple arithmetic operations plus a single spatially coherent memory fetch (depth test) and a single write to the frame- or g-buffer vs. 10+ fetches for the kd/bvh tree traversal followed by several full ray vs. tri tests (each one taking at least an order of magnitude more arithmetic ops than the sign-based test in rasterization).

I guess when we are not yet able to use Voxel Cone Tracing in AAA games, will the temporal filter or RNN based denoising really be enough to make ray traced GI worth the cost?

<comment><USER9> [This became quite a rambling post, but I'm too lazy to shorten it. Sorry.]

For a proper response to this I'd need to dig up the literature that analyzed the complexity in detail. I haven't had a reason to look at that yet. In practice, we do not care that much for theoretical complexity of algorithms. It does not tell you anything really useful. For certain problems, a grid beats a BVH, and for others, a BVH beats a grid. Sometimes, switching the heuristic used for BVH construction makes or breaks performance. Sometimes, rasterization performs worse than ray tracing.

Voxel cone tracing is at its core a volume rendering technique. It requires a brute force sampling of the generated reflectance volume at each grid cell along the ray. The dynamic generation of the volumetric data is a three- dimensional rasterization step that is not cheap. And the output is only really good for surfaces with a certain amount of glossiness. I was a bit surprised that Epic axed it from UE4 before release (implementing it takes a lot of work!), but I think in the end the combined results from reflection mapping and screen space reflections was of a similar quality. It's a shame, though, that Cyril Crassin's research work went essentially unused.

This is fundamentally different from path tracing with BVH traversal. A _lot_ of manpower and money has been sunk into the later problem in the last couple of decades. Ray intersection kernels like OptiX use every trick in the book to run fast on the hardware they are designed for - and they are really, really fast when you consider what they have to work with. Unfortunately, the hardware manufacturers are hell bent on keeping a lot of their tricks secret.

Wavelet filter based denoising really takes the rendered input down to about 1 or 2 paths per pixel. I have had that demonstrated to me in real time on quite complex scenes (one was San Miguel) - on currently available commodity hardware, too. Otherwise I wouldn't believe it. These filters make realtime path tracing work.</comment></comment></comment></comment></comment></comment></comment></comment></comment>


None of these faces are real. All made up by AIs - <AUTHOR> https://twitter.com/kevin2kelly/status/1073462307932463105 <comment><USER2> Look at the linked arxiv pdf as it has more examples showing transfer of coarse, mid, and fine features. It's also applied to cars using a different dataset and it produces results that look more natural than many actual custom mods. It also produces some distorted vehicles. We are used to greater asymmetry in faces than we are in cars.

<comment><USER3> I'm glad the cat examples are low resolution. That seemingly randomized deformity is disturbing.

</comment></comment><comment><USER4> Could they be used as actors in movies?, imagine a world where a whole movie from the scripting to the acting was done by an AI all in a few hours.

</comment><comment><USER5> I would really like to see each of the generated faces next to the 3-4 closest neighbors in the training set. I have a feeling that their claim would be seriusly diluted by such a comparison. Likely the end result is extremely close to the inputs.

</comment><comment><USER6> AI learned how to Photoshop. Can't trust photographic evidence anymore plus celebrity porn can be faked as well.</comment>


The 2018 Seed Stage Reset - <AUTHOR> http://blog.semilshah.com/2018/01/20/the-2018-seed-stage-reset/ <comment><USER2> It is rather an exaggeration to say Sequoia helped YC "get off the ground." YC was 4 years old before it took any outside money and had already invested in Dropbox and Airbnb.

</comment><comment><USER3> Another interesting new trend I've seen a few times recently: second-time founders who are not raising at all! Instead they are choosing to bootstrap to Series A or, use their profitability to defer raising inevitably.

<comment><USER4> There's a long tradition of that and honestly not really a 2018 thing imo. What it does say is that in the preceding years many people had exits and thus the raw visible numbers have gone up compared to decades past.

Ex: CEO of previous company (founded in 2007) as 3rd time founder didn't take money until the A round and was funded by his previous exits even though we were a semiconductor startup.

</comment></comment><comment><USER5> You mentioned that you would write about how SV is different than what's happening at the seed stage everywhere else. What's the tl;dr of that upcoming post?</comment>


Show HN: Euroshield protects your app from GDPR by blocking EU users - <AUTHOR> https://euroshield.xyz/ <comment><USER2> Best of luck. As a European user I look forward to the added protection this app will afford me.</comment>


How to run GUI programs on a server without any monitor - <AUTHOR> http://blog.kovyrin.net/2007/10/01/how-to-run-gui-programs-on-a-server-without-any-monitor/ <comment><USER2> You could also run a VNC server, which provides the same abilities (an X display that runs on a machine, that you can disconnect from and reconnect to later if you wish).

For people who just need to do that the topic says (rather than run apps somewhere they can't see like you need to), here's a simpler solution:

In Linux:

ssh -X user@host:appname

If you want a full X display server, run:

ssh -X user@host:Xnest

If using Windows, get Xming (a Windows X display server) first, and turn on X forwarding in Putty or your other SSH client.</comment>


Bringing SSD Performance to the DIMM form factor - <AUTHOR> http://www.sandisk.com.br/enterprise/ulltradimm-ssd/ <comment><USER3> I can't wait to see the programming paradigm of memory vs permanent storage begin to blur in the next 5 or so years. It's going to make some major assumptions about how you program stuff change quite significantly and it's really exciting.

<comment><USER4> Memristors (long promised and still not quite here) also bring together the ideas of long-term and short-term memory into one and, in future incarnations, even promise to bring computation and storage together.

<comment><USER5> When they work (there is to much cash on the table for them not too), they'll completely change the way we think of volatile and non-volatile memory. Since all memory will be non-volatile.

It'll be a huge paradigm shift in storage and IO speed.

<comment><USER6> .. and possibly give viruses more places to hide?

<comment><USER5> Unlikely. Unless we start making file systems different.

<comment><USER7> Spectators may want to archive this HN thread for posterity, because I suspect nacnud will have the last laugh. (Nacnud's comment is currently sitting at about -3 points.)

It's unlikely that future technological advancements will give malware authors more tools to work with? That seems unlikely, if history is any indication.

Imagine when you have 1TB of non-volatile storage which operates at speeds close to those we currently enjoy for DDR3 memory. Most average consumers won't use all of that space. It seems entirely plausible that a virus will write itself to some area that is never overwritten. It becomes a latent piece of malware, invisible to any filesystem, but activatable on demand by some other hard-to-detect malware. This two-step scheme would be difficult to detect since the second component does nothing except activate the first component (stored in nonvolatile storage) under some specified criteria.

Or, how about key generation or password input? Remember cperciva's post about how it was extremely difficult or even impossible to zero a memory buffer correctly? Now add in the idea that suddenly "everything is nonvolatile" and you get a perfect storm for security concerns: if a program segfaults or is terminated mid-operation, then suddenly any sensitive data it had spit out into memory might be capturable by other programs. Or, since it's nonvolatile, those secrets will persist "forever" (until they're overwritten, which may be a long, long time if storage is plentiful) and you may inadvertently leak secrets when you sell your memristor-backed storage. Whoever buys it can do some digging and uncover whatever was written into that buffer, if it's truly non-volatile storage.

So, while the future is exciting, underestimating the security implications probably isn't a good idea. We can develop new methodologies to combat the new security concerns, but new security concerns will almost certainly come to fruition. Of course, calling the concerns "new" is somewhat unfair, since new concerns are almost always very old concerns manifesting themselves in new domains, but new domains usually enable malware writers with new toolsets to exploit.

<comment><USER8> I will archive this thread to save this:

      >  1TB of non-volatile storage [...] Most average consumers won't use all of that

<comment><USER9> I'm with you I got my first 1TB HDD last year thinking it would last a few years. Nearly full now. Why? Because with all that space available I've changed how I use disk space - why throw stuff away. Also that I've moved to a higher grade camera and moved to consuming video stored on HDD rather than from discs.

When we're creating fully immersive 4D environments in place of holiday snaps then I imagine we're going to be using quite a lot of memory waving through our holiday review with friends.

<comment><USER10> > Because with all that space available I've changed how I use disk space - > why throw stuff away.

Funny, I'm the opposite. With all this bandwidth available, why keep stuff?

<comment><USER11> Because storage availability is under your control but bandwidth+remote storage availability is not. In other words, you could lose your remote stuff + access to it.

<comment><USER10> I could lose my local stuff too, by having a disk fail. I trust S3's reliability more than my local disk, so it doesn't make sense to keep things locally.

<comment><USER12> It's not just S3, it's that _and_ your local ISP _and_ the backbone it connects to. All the planets have to be aligned for your remote storage to be available.

Locally, if you're using RAID like everyone else, you just have to trust your local electricity supply and your ability not to _rm -rf /_.

Remote is fine for backups, though.

</comment></comment></comment></comment></comment></comment></comment></comment></comment></comment></comment></comment><comment><USER13> This is sort of the opposite of the RAM-based battery backed drives [1]. I can see this being immediately useful for things like large database servers: instead of re-priming caches on reboots you just have them already warmed up. You can also suddenly have a whole lot more "RAM" at the cost of its speed.

I do have a hard time picturing what this will look like if it was as fast as traditional RAM. If I can store everything in RAM, from the OS binaries, to the running processes, it certainly has a kind of elegance to it. Lots of microcontrollers already act this way: all your hardware has an address in a single address space, be at a hardware port, ROM, RAM, NVRAM, etc. However, I wonder how the modern UNIX OS will work with a system like this without block devices at all. I wonder if what it'd do is actually just use RAM disks, and years from now we'll still be doing this the way we do double emulation of the TTY. That'd be kind of sad since it means we can never get away from the concept of old block devices.

On the other hand it's damn convenient to be able to just append to a file and not have to worry about reallocating it. This means that perhaps all we'd need is a filesystem that's designed to work over RAM rather than over block devices.

[1] [http://en.wikipedia.org/wiki/I-RAM](http://en.wikipedia.org/wiki/I-RAM)

<comment><USER14> While block devices can go away, the notion of a file will probably continue to remain.

We run clusters of ephemeral linux hosts, and while we use disk, we also have plenty of hosts that run diskless. The disk mount point just becomes a tmpfs mount and the required minimal installation is made on a tmpfs partition which amounts to a trivial amount for hosting busybox and some conf files in /etc. Linux does appear to understand that tmpfs backed filestores are already in memory and do not need to synchronize pages and flush out dirty pages. That whole caching/memory layer for this fake block device is just not used at all.

<comment><USER15> Why bother?

I see two possibilities:

\- Two separate address spaces, one volatile (RAM) and one persistent (SSD). "Writing" to persistent storage is as simple as "mov [src],[dst]".

\- One global address space, with a page attribute of "volatile" (true/false). Writing is just as simple as above.

At that point the OS and userspace are free to create whatever abstractions are necessary on top. They don't necessarily need to be filesystems or files per se.

</comment></comment></comment><comment><USER16> You can tell SanDisk's performance numbers do not add up and that they are likely misrepresenting the true performance of their device. (Those red asterisks next to the numbers correspond to a footnote that is conveniently missing from the page...) A "read latency of 150usec" translates to maximum possible read IOPS rate of 1/150e-6 = 6.67K (with one outstanding I/O). But they quote a "random read IOPS of 140K". That would only be possible if their DDR3-based DIMM could process 21 concurrent read I/O operations. But to the best of my knowledge, DDR3 is limited to 8 banks/DIMM, so there could not possibly be more than 8 concurrent read I/O at any one time. Far from 21.

So SanDisk is likely quoting a _worst case_ read latency and/or a _best case_ read IOPS. Customers are left to themselves to figure out which of these numbers is most likely to represent the average performance...

PS: here is a paper with some more details but that still fails to explain this discrepancy: [http://www.snia.org/sites/default/files/SanDisk%20ULLtraDIMM...](http://www.snia.org/sites/default/files/SanDisk%20ULLtraDIMM_0.pdf)

<comment><USER17> _But to the best of my knowledge, DDR3 is limited to 8 banks /DIMM, so there could not possibly be more than 8 concurrent read I/O at any one time._

Maybe you can submit more than 8 queued requests to the controller and have them stream back at the full DDR3 data rate. Maybe it's not actually addressable as RAM, it just uses the DDR3 interface as a communication bus.

</comment></comment><comment><USER4> I appreciate this might not be the right way to look at it, but from a trivia POV, in terms of raw performance, what era of regular memory would be comparable with it? (i.e. "typical desktop memory in 2004", say.)

<comment><USER18> The read latency is about as slow as the earliest RAM ever used -- tubes of liquid mercury used as acoustic delay lines. (150 us vs. 222 us (microseconds))

[https://en.wikipedia.org/wiki/Delay_line_memory#Mercury_dela...](https://en.wikipedia.org/wiki/Delay_line_memory#Mercury_delay_lines)

</comment></comment><comment><USER19> More info on the UlltraDimms at: [http://www.anandtech.com/show/8396/fms-2014-sandisk- ulltradi...](http://www.anandtech.com/show/8396/fms-2014-sandisk-ulltradimm- to-ship-in-supermicro-servers) (developed together with Diablo, some benchmark links).

and a video interview and demo with a SanDisk manager at a computer fair - [http://www.youtube.com/watch?v=jarsTLGXx9c](http://www.youtube.com/watch?v=jarsTLGXx9c) (currently only available for OEM, requires special bios setup)

</comment><comment><USER20> 'reliability rate of one unrecoverable error in 1017 (sic) bits read'

So about 4 unrecoverable errors per sector. Seems legit.

Do people not read their own copy?!

<comment><USER21> it's 10^17. The article was probably copied and the <<sup>> got lost.

</comment></comment><comment><USER22> What would be the advantage of this comparing to PCIe/M.2 PCIe SSDs? Is it all about reduced latency, i.e. very small reads/writes would benefit?

<comment><USER5> >The benefit of using a DDR3 interface instead of SATA/SAS or PCIe is lower latency because the SSDs sit closer to the CPU. The memory interface has also been designed with parallelism in mind and can thus take greater advantage of multiple drives without sacrificing performance or latency. SanDisk claims write latency of less then five microseconds, which is lower than what even PCIe SSDs offer (e.g. Intel SSD DC P3700 is rated at 20µs).

Source: [http://www.anandtech.com/show/8396/fms-2014-sandisk- ulltradi...](http://www.anandtech.com/show/8396/fms-2014-sandisk-ulltradimm- to-ship-in-supermicro-servers)

 __TL;DR __about 4x faster then PCIe SSD 's

<comment><USER23> But raw flash writes on the order of 1-2 milliseconds, so the 5 microseconds must be the latency to write to a ram cache inside the stick. I wonder what the latency would be for a write larger than the buffer. For that matter, how large is the buffer?

<comment><USER5> If you read the source you will see that no independent benchmarks have been done yet.

<comment><USER23> The article did update with a benchmark link comparing a couple of models to a fusion io card.

[http://www.percona.com/blog/2014/08/12/benchmarking- exflash-...](http://www.percona.com/blog/2014/08/12/benchmarking-exflash-with- sysbench-fileio/)

So the 95%, write latency is 1-1.5 msec for one model, and 2.5-3.5 msec for another model. Maybe representing SLC/MLC flash?

95% read latencies are maybe 350 or 250 usec.

</comment></comment></comment></comment></comment><comment><USER24> I don't quite understand. Does this act like a stick of memory or an SSD? Is it just using the memory controller as a super fast parallel bus? If it does act like normal memory, what happens at reboot?

<comment><USER25> Answer is there in FAQ. Written data is not lost on reboot, so basically you can mount it as a `ramdisk` partition and use that as data directory for your database. I have used this approach in past to speed up large test suite of a web application, except it required restoring from some sort of backup on reboot. Which won't be necessary in this case.

<comment><USER26> Does this mean you won't have traditional memory available at all (outside of L1-3 cache)? Or is it able to mix and match between real DDR3 memory and SSD?

</comment></comment></comment><comment><USER27> For all of us who are thinking "it's just like RAM, just persistent!", here's some perspectives about what persistent RAM means for OSes and applications: [http://lwn.net/Articles/610174/](http://lwn.net/Articles/610174/)

</comment><comment><USER28> This is pretty cool, especially since the data is persistent. You could put an entire data warehouse onto one or of a couple of these things, update it once a week and get amazing response time.

But I thought the main drawback of SSDs was that eventually the individual memory cells will degrade and lose the ability to write new data. I don't see anything about endurance other than a MTBF of 2.5 million hours and the disk- writes-per-day (DWPD), which I had to look up. I have no idea if these are good or bad. I feel like these things will be great if you didn't write new data a lot, or you have deep pockets to replace them when you need to.

<comment><USER29> 2.5 Mhours MTBF equates to 285 years. That's a long time.

On any kind of large-scale installation you need redundancy, but if those numbers pan out then you could expect any _single_ SSD to outlast your organisation.

Take backups anyway.

<comment><USER30> At what duty cycle? The MTBF rating means literally nothing without that detail.

</comment></comment></comment><comment><USER31> How come read latency is 150 µs, while _write_ latency is 5µs, 30 times shorter? Do they mean the latency to start a write operation? IIRC, flash memory is written block by block, with a pretty significant time to write one block.

<comment><USER32> At a guess, they are using MLC (or even TLC) transistor configurations, which effectively packs more bits into on transistor, but is slower to read. Good SLC has read cycles of 20-25 usec.

</comment></comment><comment><USER33> The capacities are very odd - you'd expect something in a DIMM format to have a power-of-2 size.

I think the market for this could be _much_ bigger if it behaved like a regular RAM DIMM, only slower and nonvolatile; it somewhat reminds me of old machines that used magnetic core RAM. This could be useful for laptops, like a zero-power suspend-to-(NV)RAM. The only thing that is worrying is the endurance of the flash - especially if it's being treated almost like RAM in this application.

<comment><USER34> It's still _way too slow_ to be treated as RAM. The performance they quote is equivalent to a mid to lower range PCIe SSD.

For comparison, the stated read performance is 800MB/sec or so. Last time I checked - on ca. 8 year old hardware, we could read files from a RAM disk under Linux at a rate of about 6GB/sec. That's with the added overhead of the benchmark software running and going through a filesystem.

<comment><USER35> I wouldn't say that 800MB/s is slow.

[http://en.wikipedia.org/wiki/PC133](http://en.wikipedia.org/wiki/PC133)

I also wonder if that 880 is for just one slot filled up. If it is, then I wonder if you can parallelize to 4 slots for ~3.4GB/s.

At that point, I imagine many types of data sets would work A-OK.

Though I wonder how that's scaled for cores, given that in the situation I imagined above, you'd be streaming all that data to just one CPU to get that aggregate bandwidth.

Hmm.

OK what about some other scenarios? Being able to have RAM and Storage on a sliding partition is sort of cool. I wonder if it'd make provisioning VMs any easier. "How much RAM do you want? Set the slider!"

<comment><USER34> Yes, it is slow. PC133 is "ancient". As I pointed out, even in 8 year old hardware it was trivial to get more than 6 times that performance out of a RAM disk device using filesystem benchmarking tools.

> If it is, then I wonder if you can parallelize to 4 slots for ~3.4GB/s

You probably can, but then you can't _run_ code straight out of it, or read/write data directly as if it is normal RAM. Putting a filesystem on it, RAID'ed over multiple slots will likely work great (especially so since it's easy to get servers with a ton of DIMM slots, and it'll allow much better server density than trying to fit in more drive slots). But treating it as RAM will be _slow_.

</comment></comment></comment></comment><comment><USER36> I look forward to the point where 3/4 of business application code will go the trash when we'll have a persistant memory with the latency of actual RAM disk (Memristor !!). Exit all that "copy from RAM to Disk/Network" code. It will definitely change the way we code and look at code. That's why nowadays I think a good interface to your entities, like the Repository pattern, is a must have.

<comment><USER37>
        It will definitely change the way we code

Only on a low level, right? I have not been thinking about ram and disk in ages. I calculate with variables, I store stuff in a DB or in a file, I access the net via http. Nothing would change if ram increases I think.

<comment><USER38> Well, if you have plentiful persistent RAM an application could easily "suspend" itself (on shutdown for example), and then resume running at a later point in time. The code would not have to think about this, since the entire state is just snapshotted. It's basically what machines do now when they "hibernate", except more effecient and could even happen if the power got cut.

Additionally I suppose your variables could also be persistent automatically. Though the biggest change I see is that software would never really need to completely close anymore when RAM == Disk. For RAM usage it wouldn't really matter if they were running or not, unless they delete data upon shutdown. To save CPU or other IO usage the application could simply be suspended.

<comment><USER39> Can't wait for the persistent memory leaks!

<comment><USER40> Or losing data on crash because load/save cycle is untested.

</comment></comment></comment></comment></comment><comment><USER41> Is the advantage the low latency because the rest of the specifications seem to be pretty standard for an SSD. Does this require a BIOS patch of some sort?

<comment><USER25> I suppose the main usage will be a RAMDISK mounted partition which will not lose its data on Server reboot, power loss or when program is not running.

I don't think this SSD can be accessed through regular SCSI, IDE, AHCI controllers. [http://www.sandisk.com.br/enterprise/ulltradimm- ssd/](http://www.sandisk.com.br/enterprise/ulltradimm-ssd/)

<comment><USER42> Yes it would be very cool to have the entire operating system in SSD. Literally flick the computer on and it's running ;)

Or flick rapidly between Linux and Windows. That makes me think it might be wise to have a manager to do this. E.g. leave the disks accessible between three+ operating systems.

<comment><USER43> _Yes it would be very cool to have the entire operating system in SSD. Literally flick the computer on and it 's running ;)_

Isn't that what you already get with suspension to memory (S3)? At least on my Debian laptop, it's ready before the lid is fully up.

<comment><USER44> Right, except:

\- S3 uses battery power (albeit not much)

\- NVM provides protection from power faults in datacenters

</comment></comment></comment></comment></comment><comment><USER45> We have PCIe SSDs approaching 7.2 GB/s. While that's lower than DDR3 speeds, it's not that far off.

[http://hothardware.com/Reviews/OCZ-CES-2012-Product-Tour- ZDr...](http://hothardware.com/Reviews/OCZ-CES-2012-Product-Tour- ZDrive-R5-Everest-2-Step-Out/)

</comment><comment><USER46> I would still say that the real performance bottleneck is ultimately the bandwidth between the CPU and this memory. This suggests that the next stage will be to incorporate heterogenous processors alongside that memory - <USER2> upgrading your computer could then be as simple as plugging in an another combined non-volatile memory/CPU block into a fast inter-connector. Rather reminds me of the the old S100 bus where everything just plugged into the same channel, (which probably dates me quite well).

</comment><comment><USER47> This technology is actually developed by a company called Diablo Technologies. They seem to have licensed it to Samsung.

<comment><USER48> Do you mean SanDisk, or does Samsung also play into this somehow?

<comment><USER47> My bad, I meant SanDisk.

</comment></comment></comment><comment><USER49> Cool! And weird. I wonder what the OS support looks like.

Also available in a non-Brazilian page at [http://www.sandisk.com/enterprise/ulltradimm- ssd/](http://www.sandisk.com/enterprise/ulltradimm-ssd/), of course. :)

</comment><comment><USER50> I honestly can't imagine having something in my DIMM slots with this bad of latency and throughput. 150 microsecond reads? Doing a full POST would take forever. What OS and software use - case does this serve?

<comment><USER34> You'd put a filesystem on it and mount it as a "ramdisk", with the result that you can cut out expensive RAID controllers and/or PCIe SSDs, and can potentially reduce form factor.

E.g. I can get 1U servers with 32 DDR3 slots and 64 cores, but only space for 3x 3.5" drives, or if you double up (but few chassis will then let you use hot swap caddies), 6x 2.5" drives.

You could easily fit 256GB RAM and still have 16 slots free for RAID arrays over those DIMMs.

</comment></comment><comment><USER51> Apparently once you hit 3.2TB the IOPs falls to only 200K. Typo? [http://cl.ly/image/2J0u182D3229](http://cl.ly/image/2J0u182D3229)

</comment><comment><USER52> SSDs as RAM + projects like Tachyon are the future of big data processing -- current workflows are still way too slow. I wonder how this will affect Spark.

<comment><USER53> I am not a silver bullet kind of person, but I think this kind of technology plus things like Spark are potentially the holy grail. Ok, let me rephrase - I've often believed that there was a sort of "ultimate architecture" with distributed cluster computing, distributed programming frameworks, high-speed interconnect, and flash based storage. I think we are getting closer and closer each day. I wish I worked in R&D at any of the companies doing this fundamental research now - I have a feeling they have some amazing things cooked up behind closed doors.

</comment></comment><comment><USER54> Do OSes already support this? Do they support it as memory, a storage device, or both?

</comment><comment><USER55> What OS support exists for this, and how does it work?

<comment><USER47> You need not just OS support but specific motherboard too. Currently AFAIK this is only supported on SuperMicro dev kits.

<comment><USER56> Wouldn't mounting the RAM stick as a ramdisk be enough though?

<comment><USER55> You can't address a specific RAM stick, typically.

Try and boot an OS without knowledge of this, and it'll start using the stick like it uses RAM. It'll take orders of magnitude longer to boot, to the point of impracticality, probably (I haven't calculated).

The OS needs to understand the memory map, and at the minimum exclude use of the stick for "normal" operations.

Then, it needs to expose the stick for access - preferably in a way that is more usable than /proc/mem.

</comment></comment></comment></comment><comment><USER57> What implications does this have for us simple folk?

</comment><comment><USER58> What's the catch here?

<comment><USER59> It still costs 10x disk, even though both are fantastically cheap compared to decade ago.

Flash still has limited write cycles. Its for data you probably wont write more than once an hour, but not virtual memory.

<comment><USER60>
      > Flash still has limited write cycles. Its for data you probably wont write more than once an hour, but not virtual memory.

You can write data to SSDs a lot more than once an hour, even virtual memory. The drive's firmware (assuming it does its job) will do wear-leveling and spread the logical writes across different physical locations on the drive.

If you write 20GB of data per day to a modern 480GB SSD you can expect 25 years of service. (Realistically, something else will probably fail before then)

Example - [http://www.anandtech.com/show/8520/sandisk-ultra-ii-240gb- ss...](http://www.anandtech.com/show/8520/sandisk-ultra-ii-240gb-ssd-review)

</comment></comment></comment><comment><USER61> FTA:

"Reduces total processing time, compared to hard-drive drives (HDDs)."

i loled.

<comment><USER62> I couldn't believe that either... it's kind of sad.

</comment></comment><comment><USER63> Mind blown.</comment>


The inventor of Apple iOS user interfaces - <AUTHOR> https://patents.google.com/?inventor=Bas+Ording <comment><USER2> The proximity sensor was the key that made the iPhone work. When people say some other company invented the touchscreen smart phone first, I like to ask, did it have a proximity sensor?

<comment><USER3> You could say the same about the use of a capacitative display on glass rather than a resistive screen you operate with a stylus, or the high (for 2007) pixel density, or the smooth (for 2007) UI and animations, or inertial drag- to-scroll, or a whole bunch of other things the iPhone did first to make a touchscreen smart phone pleasant and enjoyable to use. I know that when I first used the OG iPhone, drag-to-scroll was the first thing that really felt like magic to me.

In reality, it's the combination of all those things and more that made the iPhone work, made it more appealing than anything Palm, RIM or Danger made. Just adding a proximity sensor, or one of the other things to that list, to a Palm Treo wouldn't have made it an iPhone.</comment></comment>


Comcast defends against Google Fiber with 2 Gbs home Internet service in Atlanta - <AUTHOR> http://www.networkworld.com/article/2905687/opensource-subnet/comcast-gets-defensive-with-2-gig-fiber-service-gigabit-pro.html?nsdr=true

<comment><AUTHOR> It looks like Google's strategy to promote faster internet worked. Google gave the impression that it wanted to compete with Comcast when it first announced Google Fiber in Kansas City. But Google really wanted to create demand for hyper-fast internet because the company's ability to monetize its users increases proportionally with internet access speeds.

<comment><USER2> I think google _can_ compete with comcast.

The US is so conditioned to ridiculously priced broadband that we don't realize how cheap it can be.

There's a service in Tokyo that's 2GB for ~50 USD.

Google is showing that you don't have to price gouge to be profitable, and it's terrifying the entrenched oligopoly.</comment></comment>


50 Web Developer Documentation Manuals You Need To Know About - <AUTHOR> http://geekli.st/JasonDavis/links/468

<comment><USER2> Couldn't link to the actual list of documentation manuals?

[http://www.codedevelopr.com/50-web-developer- documentation-m...](http://www.codedevelopr.com/50-web-developer- documentation-manuals-you-need-to-know-about/)

It is a nice list of documentation/references to have.

<comment><USER3> And then its just a list of links to various project home pages. I'm sure that if you do stuff with PHP you know about php.net.

I flagged this.</comment></comment>


Nearly All Binary Searches and Mergesorts Are Broken (2006) - <AUTHOR> https://research.googleblog.com/2006/06/extra-extra-read-all-about-it-nearly.html <comment><USER2> As I was saying over at [1], if you're going to do program proofs, you have to prove absence of overflow. It's the cause of many program bugs.

[1] [https://news.ycombinator.com/item?id=12146049](https://news.ycombinator.com/item?id=12146049)

<comment><AUTHOR> Oh yeah, I actually saw the link in your comment!

At the risk of sounding stupid, I had a question about the following solution:

        int mid = (low + high) >>> 1;

I understand that right shift is like dividing by 2, just like in decimal right shifting the digits is like dividing by 10 (654/10 = 065). But why can we just ignore the low + high overflow issue? Is it because the overflow will be stored in the two's complement bit and right shift doesn't care about what that bit represents? If unsigned ints were used instead, I suppose that trick wouldn't work?

<comment><USER3> low and high are assumed to be positive and at most 2^31 - 1. So, there is a zeroed high bit in each which, for a signed int, is reserved to indicate negation.

When low and hi are summed together, the high bit of the result might be set. For a signed int, this would be an accidental overflow and would be falsely interpreted as a negative number. However, if you interpret the result as an unsigned int, it would be the correct sum.

The Java logical shift operator >>> does not retain the sign when shifting. So, it will always shift a 0 into the high bit, making the result a positive signed int.

In most C implementations, >> is an arithmetic shift, which would retain the sign in the result. So in C, we would need to cast low and high as unsigned first; otherwise, the high bit will be retained rather than shifted.

</comment></comment></comment><comment><USER4> Hmm, I always figured it was just assumed that, unless otherwise specified, most well-known implementations fail with sufficiently large numbers.

<comment><USER5> Yep, this is just vintage click-bait.. you can bet more than sorting routines will fail with numbers approaching 2^63. It doesn't matter because if you're running quick sort on a list of 2^64 entries then something else is going wrong before your (l+r)/2 has a chance to overflow.

<comment><USER6> If you're trying to sort 2^63 items at once, you have other problems.

</comment></comment></comment><comment><USER7> Prior discussions: [http://news.ycombinator.com/item?id=621557](http://news.ycombinator.com/item?id=621557) [http://news.ycombinator.com/item?id=1130463](http://news.ycombinator.com/item?id=1130463) [http://news.ycombinator.com/item?id=3530104](http://news.ycombinator.com/item?id=3530104) [https://news.ycombinator.com/item?id=9857392](https://news.ycombinator.com/item?id=9857392) [https://news.ycombinator.com/item?id=6799336](https://news.ycombinator.com/item?id=6799336)

</comment><comment><USER8> > I was shocked to learn that the binary search program that Bentley proved > correct and subsequently tested in Chapter 5 of Programming Pearls contains > a bug.

Huh? How did he _prove_ it correct, then?

<comment><USER9> On an idealized machine with arbitrarily large integers I assume.

<comment><USER10> How else do you "prove" trivial algorithms other than by removing the realities of an actual runtime environment?

I'm pretty sure you're right though. Integers must have been defined as infinite in the proof for it to have been a proof at all.

<comment><USER9> If you sufficiently specify the runtime environment the proof can still work: Since the array is composed of integers, many C compilers/machine architectures will dictate a maximum size of the array s.t. there can't be overflow.

<comment><USER10> Touche, and fair enough- although you would expect them to call out that limitation since it's both critical and highly un-general. Bytes are comparable, small, and common enough to at least accommodate an exclusionary statement in the proof.

</comment></comment></comment></comment></comment><comment><USER11> At least, in a memory-safe language, you'll get an IndexOutOfBoundsException rather than corrupting memory, which can be used as an attack.

</comment><comment><USER12>
        int mid = (low + high) >>> 1;

I don't get how this fixes anything, the overflow still occurs.

Why not simply

        int mid = (low/2) + (high/2) + (low & high & 1);

<comment><USER13> More expensive.

Here's another approach: represent the range as a (low, length) pair instead of (low, high). The update becomes either length /= 2 or low += length/2, length -= length/2\. IIRC this was what I did when I adapted Bentley's code to C 25 years ago, mainly because of overflow. It never occurred to me to check if standard libraries got it wrong.

</comment></comment><comment><USER14> All of those proposed solutions still fail on valid arrays that are to large. We changed to 64 bit OS and you now 32 bit indexes just don't cut it.

<comment><USER10> Not in java (arrays can only be indexed by a signed 32 bit integer) and the C++ solution works exactly the same way with the full 64 bit data types. That much should be obvious, and if you think you might legitimately exceed two billion elements in the array you're sorting- you'd be a fool to rely on someone else's sort implementation.

<comment><USER14> Java uses shorts in some JavaCard implementations. So, it's clearly just a legacy limitation which will eventually be removed.

As to C++ 2+ billion byte arrays are not uncommon. It's just a few gigs of ram for int[] arrays.

</comment></comment></comment><comment><USER15> > int mid = low + ((high - low) / 2);

Why this instead of the more intuitive `low/2 + high/2` ?

Edit: Nevermind, I get it. The reason is instructive: In the case where high and low are odd numbers, the "more intuitive" way is off by one.

</comment><comment><USER16> A more interesting version of that bug, I find, and the reason why I almost never used unsigned values in my algorithm is that when you compute indices in a non-trivial way, any intermediate value that is negative will break your program.

</comment><comment><USER17> > It is not sufficient merely to prove a program correct; you have to test it > too.

No, this just indicates that you didn't prove it rigorously enough :p</comment>


Ask HN: How do you self-promote your projects to get views? - <AUTHOR> <comment><USER2> Extensive list of places where you can post: [https://github.com/mmccaff/PlacesToPostYourStartup](https://github.com/mmccaff/PlacesToPostYourStartup)

<comment><AUTHOR> Awesome! Thanks!</comment></comment>


MythBusters Results – List of Myths and Summaries - <AUTHOR> https://mythresults.com/ <comment><USER2> There is also a fairly large community around editing Mythbusters episodes ("streamlining") so that each myth is one single block rather than the interspliced variant that was aired[1]. They've recently completed all aired Mythbuster episodes too.

[1]: [https://www.reddit.com/r/smyths](https://www.reddit.com/r/smyths)

<comment><USER3> Thanks for the link!

The Community Details: Edits of Mythbusters episodes _(all the fluff removed)_

They probably get minified ratios that make js devs jealous.

</comment></comment><comment><USER4> > A sailboat stranded in calm water can move forward using an on-board fan to > blow air into its own sail.

That's surprising! I'm guilty of spreading misinformation. :)

<comment><USER5> Sails are crazy efficient, and are most effective when wind is blowing across the bloat. So if you point a fan across the boat you'll get a forward force vector and sideways force vector.

Edit: Based on the summary of the episode provided it looks like mythbuster didn't exploit this property of modern sails.

<comment><USER6> And this (Magnus effect), which still amazes me: [https://en.wikipedia.org/wiki/Rotor_ship](https://en.wikipedia.org/wiki/Rotor_ship)

</comment></comment></comment><comment><USER7> Can someone do this for the British quiz show QI (quite interesting).</comment>


Stripe launches in Australia - <AUTHOR> https://stripe.com/blog/stripe-in-australia

<comment><USER2> For anyone from Stripe reading this, having a '401k' plan for Australia makes no sense, but is listed on the AU hiring page.

<comment><USER3> (I work at Stripe.)

Don't worry, the benefits box just isn't localized (yet). We have a draft of a new jobs page we're working on, but figured we should prioritize launching products over it :).

<comment><USER4> Products are more important than people. Good to know.

<comment><USER5> The people are presumably getting a proper retirement plan even if the copy isn't fixed on the website yet, and customers are people too.

</comment></comment></comment></comment><comment><USER6> I wonder if Stripe is planning to launch in New Zealand any time soon - it's very close to Australia :) I'm really keen to stop relying on Paypal for accepting payments.

<comment><AUTHOR> We are working on New Zealand, but don't have an immediate ETA for an New Zealand beta. Sign up at [https://stripe.com/global](https://stripe.com/global) to be notified when we launch

<comment><USER7> That is amazing news. Payments are absolutely horrible in NZ, I have been desperate for Stripe to be here for the longest time :)

<comment><USER6> What are you using now?

<comment><USER7> Using Paypal at the moment, as te_chris said PX pay is decent but requires a merchant account which is expensive and slow to setup. As far as I am aware their aren't any other decent solutions. Kiwipay could be good but at the moment it isn't really suitable for anything more than casual payments.

<comment><USER6> Aside from merchant account setup, last time I looked (4 years ago), Payment Express worked out to be really expensive when charging in USD. I think it was in part due to merchant account/currency conversion charges by the bank. It was significantly more expensive than Paypal. I don't know if the situation has changed since then.

<comment><USER7> I know that the only bank that allows international currency transactions is BNZ so they are likely fairly expensive seen as they have an monopoly on it.

<comment><USER8> Technically (for those who don't know) they allow multiple currency transactions from one/single account. So you may have 1,000 NZD but it's made out of USD, PHP, AUD etc

</comment></comment></comment></comment></comment></comment></comment></comment><comment><USER9> The currency support that hit the AU beta a month or two ago was the big one for me, but the low rate (1.75% + 30c for Australian cards) is a nice touch for those who might normally smash their heads against a bank's merchant API, PayPal or someone like eWay (who I don't have nice thoughts about).

<comment><USER10> What would be an example of a traditional rate with other merchants in Australia?

<comment><USER9> eWay is $49/setup + 2.9% + 30c per transaction at the low end ([http://www.eway.com.au/pricing/popular- plans](http://www.eway.com.au/pricing/popular-plans)), which is their closest option to Stripe. Now, trying to read their API docs is another thing entirely: they give you a PDF with a couple of examples and that's it - [http://www.eway.com.au/docs/api-documentation/token- payments...](http://www.eway.com.au/docs/api-documentation/token-payments- field-description.pdf?sfvrsn=2)

PayPal Express Checkout starts at 2.4% + 30c (across all trans). One might use PayPal for other reasons than just their fees (i.e. your user demographic) but their API is still a mess.

<comment><USER11> It's completely anecdotal, but we've used eWay for the past 2 years. They've been slightly cheaper than the alternatives and pleasant to deal with for the most part, but any technical interaction has been incredibly painful. The dashboard is a pain to use, and they generally seem oblivious to trends in payment gateways.

In addition, two months ago we were unable to process payments for a period of a few hours due to an SSL error on their secure payments API. Any customer not using a hosted payment page was affected. From what has been communicated to me it was an issue with their CDN provider, but I'm still waiting on the full details. I understand things happen, but a lack of communication from someone who processes your payments is really frustrating.

On the other hand, Stripe have been really nice to deal with, and integration has been a breeze. Things might change once we put it into production, but I'd be surprised if they got worse.

</comment></comment></comment></comment><comment><USER12> Will anyone who signed up for pin be moving to stripe?

<comment><USER13> Been with PIN since the start.

Will only move if Stripe introduces the 2 day bank transfer feature that the US has.

<comment><USER14> Happy to offer 2-day settlement (we've got a number of merchants on this already). E-mail email@example.com.

</comment></comment></comment><comment><USER15> Finally! Where I work we're already discussing moving every (all 6 of them) project that we're working on at the moment over to Stripe. I'm so happy, this was a great start to my Tuesday morning!

<comment><USER16> Can I ask why Stripe and not Pin? I've been using Pin for a number of different projects and have been really happy with it.

Curious why Stripe seems to be the default alternative to PayPal/eWay etc, even though Pin has been established in AU for a while now.

</comment></comment><comment> ux-app fantastic news! I just finished a Stripe integration a day or two ago. Everything I had heard about stripe was true. I've done eWay, PIN and now Stripe integration and Stripe is hands down the easiest to get up and running.

Subscriptions in particular are very well designed. Their documentation is outstanding. I was up and running with a multi-tiered subscription setup in 1 day. The checkout flow is particularly awesome.

</comment><comment><USER17> For the uninitiated, is there benefit in using Stripe (etc) over a bank merchant facility, when your business is already transacting $80,000+ per month?

Working with an Australian client at the moment about moving more sales online - I don't want to hold back information about other payment processors, but can't see any benefit over their existing bank facilities. What am I missing?

<comment><USER18> I'm not sure what your conclusion would be, but don't assume that your client is correct about their real cost of transacting.

In Australia, banks will usually offer an online merchant account and a payment gateway (you can also use a third party like eway). When I worked in Australia I usually found that using a third party payment gateway worked best in terms of price. The UI can also matter. Some clients spend a lot of time in there manually processing, reviewing, refunding transactions, running reports, etc.. I had good reports from clients using Eway. Bad reports from clients using NAB. (This is 5+ years ago, so YMMV).

If the difference in price isn't really relevant in absolute terms to the overall cost of the project, I would always strongly recommend the option with better software & customer support.

The pricing structures can be complicated. If you really want to understand them, it's better to run it as an audit. What did it cost the client in the last 12 months. What would it cost them using stripe. Take into account monthly fees, per transaction fees (depends on transaction size and on volume), any anti-fraud fees, chargeback fees. You can actually send the info to stripe (or another third party gateway) aand they'll probably do the analysis for you.

You will probably find that your client is actually paying a little more than they think they are.

<comment><USER17> Thanks netcan, that's a lot of really useful information.

</comment></comment></comment><comment><USER19> Great to see you guys coming to Asia-Pacific.

Can some Stripers on this thread give an estimate as to when Stripe will come to Hong Kong or Singapore?

I am bootstrapping a side project with a colleague and literally the only reason to even consider a UK partnership over a Singapore or Hong Kong one is that we want to use Stripe (or whatever clone gets there first).

</comment><comment><USER20> Great news. I have built a number of MVPs for startups that will be very happy to move from PayPal.

</comment><comment><USER21> I'm so excited for the Norwegian beta! Been needing Stripe for a project for ages!

<comment><USER22> Me too! I just noticed. I think I've signed up to be notified 40 times.

</comment></comment><comment><USER23> Awesome! Can't wait until Stripe is launching in Denmark, hopefully soon!

<comment><USER24> We actually launched our Danish beta earlier this morning: [https://twitter.com/stripe/status/491224812958650370](https://twitter.com/stripe/status/491224812958650370). You can sign up for an invite over at [https://stripe.com/global](https://stripe.com/global).

<comment><USER25> Any plans for NZ? As you can see with the success of EFTPOS here, we have a history of adopting new payment technologies quickly. I personally have an idea that's just waiting for a proper mobile payment system.

<comment><AUTHOR> Yup! [https://news.ycombinator.com/item?id=8066572](https://news.ycombinator.com/item?id=8066572)

</comment></comment></comment></comment><comment><USER26> This is fantastic! We've recently gotten a bank's merchant account and eWay as a gateway, but I've been impressed with neither. I'm so glad that Stripe is now available here.

</comment><comment><USER27> Awesome! I've been waiting for Stripe here down under for ages!

</comment><comment><USER28> Someone needs to fix payment culture in Australia and also in Europe. Going to the bar with a large group of people and either paying with:

A) A pocket full of coins

B) A card but only being allowed to pay with one or two for your whole group, is just straight up silly.

Situation B happened to me a million times while I was down there for a year and it's just an annoyance, and carrying a kilo in coins is no fun either. I actually submitted a suggestion to ANZ for them to make some sort of group payment option for restaurants but heard nothing back and couldn't pursue. Hopefully someone can make something easy with Stripe.

<comment><USER8> Use... Notes?! You know, money... Coins?! Who uses coins? Secondly nobody is going to refuse 5 payments from 5 cards either or they don't get paid. Simple.

</comment></comment><comment><USER29> What actually prevents Stripe from just being international?

<comment><USER9> > What actually prevents Stripe from just being international?

The need to partner with a local bank to provide merchant services/accounts. i.e. Pin Payments partners with NAB in Australia, with NAB setting up an "invisible to the user" merchant account. It's part of their model - you just deal with them, not the bank, not anybody else.

<comment><USER29> I get that's _what_ they do but why do they need to do that for each individual country instead of just running everything through their own bank + only subject to their own state/federal regulations?

</comment></comment></comment><comment><USER30> Sweet! And is Stripe going to obtain stripe.com.au ?

</comment><comment><USER31> Come to ZA please!

<comment><USER32> Absolutely. It would crush the market.

</comment></comment><comment><USER33> Nice work peeps! Definitely needed for Australia.

<comment><USER13> Yep, amazingly during BETA a major competitor dropped its monthly fee ;).

<comment><USER34> Going to be tough for that competitor to survive if they don't pivot from a 'Stripe-clone'. Hope they're well funded and well backed.

You need to do a huge volume of transactions to be able to live off 2.6% + 30c, close to two million a month to support a startup with 5 fully loaded employees including the founders.

Working with a lot of Ecommerce sites I know a well established one (attached to 3 bricks and mortar stores) does on average $16k a month. Say on average an Online store is doing 10k/month you're looking at 200 clients to keep the payment processor afloat. Doable but you'd want them to have some runway otherwise people are gonna go with Stripe to know they've got a payment gateway that's not gonna disappear

</comment></comment></comment><comment><USER35> Is Stripe Japan on the anvil?

</comment><comment><USER36> What took you so long Susan!</comment>


Identifying satellite interference due to GSM rebroadcast (2011) [pdf] - <AUTHOR> http://data.satirg.org/wp-content/uploads/2015/11/2011a-GSM-re-Broadcast.pdf <comment><USER2> Tracing down RFI sources can be immensely challenging - I remember reading of one case where the tower itself became a radiating element and a source of RFI.

[https://www.thebdr.net/articles/warstories/trenches/trenches...](https://www.thebdr.net/articles/warstories/trenches/trenches-A2x4Fix.pdf)

Here is another where the source of the RFI was a totally unexpected source.

[https://www.thebdr.net/articles/warstories/neighbors/bug.pdf](https://www.thebdr.net/articles/warstories/neighbors/bug.pdf)

</comment><comment><USER3> For an example of more malicious interference, see [https://en.wikipedia.org/wiki/Captain_Midnight_broadcast_sig...](https://en.wikipedia.org/wiki/Captain_Midnight_broadcast_signal_intrusion)

<comment><USER4> Even weirder and more wonderful, and still no one knows who it was: [https://www.youtube.com/watch?v=tWdgAMYjYSs](https://www.youtube.com/watch?v=tWdgAMYjYSs)

</comment></comment><comment><USER5> "Bandwidth limit exceeded"

Here's the same PDF from the Internet Archive:

[https://web.archive.org/web/20170930150048/http://data.satir...](https://web.archive.org/web/20170930150048/http://data.satirg.org/wp- content/uploads/2015/11/2011a-GSM-re-Broadcast.pdf)

</comment><comment><USER6> I'm sorry for asking this, but can anyone tl;dr the slideshow? The satellite was blindly receiving and rebroadcasting signals from a misbehaving cell tower?

<comment><USER3> [https://news.ycombinator.com/item?id=15371607](https://news.ycombinator.com/item?id=15371607)

<comment><USER6> So the satellite was rebroadcasting the signal at a frequency where it could interfere with GSM? Does the satellite just rebroadcast whatever it receives, verbatim?

<comment><USER3> Block up-converter (BUC) at uplink site (in this case, likely part of a VSAT terminal or Satellite Internet "antenna") takes L-Band (950-1525mhz) input via cable, converts it to C-band uplink (5850-6425mhz) frequency, and transmits to satellite. Satellite then rebroadcasts verbatim at C-band downlink frequency (3400-4200mhz). Except that one of the inputs didn't have a cable or filter attached so it picked up a GSM signal at 936-960mhz. This caused interference on the satellite.

<comment><USER7> For further context, the reason for this slightly convoluted setup is that normal coaxial cables are really lossy at the high frequencies used to communicate with satellites, so most systems use lower frequency bands on the cable runs and convert the signals by a fixed frequency offset at the actual antenna. It just so happens that the block of frequencies used on the cable runs is similar to common mobile phone frequencies.

</comment></comment></comment></comment></comment><comment><USER8> Now that was some debugging! Especially liked the part where they grabbed an old GSM to decode the signal. KISS at its best

</comment><comment><USER9> Context? Why was the signal being rebroadcast? What was the point?

<comment><USER3> TLDR: Unterminated input port at satellite uplink site acted as antenna, picking up nearby cell tower by accident. Fix: put a terminator on the port.

</comment></comment><comment><USER10> (2011)

<comment><USER11> Added. Thanks!</comment></comment>


Caddy 0.9 Released with All New Core - <AUTHOR> https://caddyserver.com/blog/caddy-0_9-released <comment><USER6> There are some features in Caddy that are simply outstanding - HTTP/2 and Let's Encrypt integration, to name a few - both pretty much work out-of-the- box with zero-configuration.

On the other hand, there are still some gaping holes - for example, to block (or allow) a 192.168.0.0/17 IPv4 subnet in Caddy, one needs to do all of below:

\- Install an addon [1];

\- Which used to require recompilation, with 0.9 release you can just click an option during download, yay!;

\- Add 128 ranges to cover this single subnet: 192.168.0.0-255, 192.168.1.0-255, ...192.168.127.0-255. Configuration doesn't support subnets, only ranges. And only ranges in last octet, i.e. 192.168.1.0-255 (meaning 192.168.1.0/24), or implied ranges by trailing octet(s) omission, i.e. 192.168 (meaning 192.168.0.0/16) [2].

Oh, and ipv6 filtering doesn't exist at all.

[1] [https://caddyserver.com/docs/ipfilter](https://caddyserver.com/docs/ipfilter)

[2] Which is mildly confusing notation too, since traditional UNIX inet_aton() call would interpret this as 22.214.171.124. Try typing "ping 192.168" on Linux.

<comment><USER7> >simply outstanding - HTTP/2 and Let's Encrypt integration

Simply simple de facto features basically are called outstanding now?

<comment><USER8> Which other web server software intended to replace nginx or apache has HTTP/2 or Let's Encrypt as built-in functions?

</comment></comment></comment><comment><USER9> Shameless plug: if you're interested in knowing more about the Caddy webserver, I did an interview with Matt Holt - its creator - a few weeks ago on the SysCast podcast: [http://podcast.sysca.st/podcast/1-matt-holt-creator- caddy-we...](http://podcast.sysca.st/podcast/1-matt-holt-creator-caddy- webserver/)

</comment><comment><USER10> I would love to hear experiences from people/companies using Caddy in production (for example, replacing nginx). The project looks very promising, but for production usage one might also like a decent group of other people using it in production.

<comment><USER11> I only use it to host a couple low traffic personal sites but so far it's been fast & reliable. Configuration is easy because things like SSL cert management are baked in. It's perfect for my needs. Not sure if I'd recommend it for anything with a lot of diverse traffic, but it serves up basic WordPress blogs and node.js apps fine.

</comment></comment><comment><USER12> The one thing that bothers me (which is not Caddy's fault at all) is the plugin system. If I understand correctly, I have to recompile Caddy for every plugin I want to use, right? Sounds like a limitation with Go which is really unfortunate.

<comment><USER13> Isn't that the same for Nginx? You still have to compile when you add new plugin?

Caddy is very easy to use. You can download the build with what you want from their download page.

The nicest thing about it is very simple config file, TLS out of the box, automatically renew as well.

<comment><USER14> I'm not a big fan of this either. Now you need to keep track separately of what your snowflake build enables, and when it's time to update, or if you want to add something else, then you need to go back and fill out the form manually again, and update manually.

Also, it makes distro packaging dreadful, since you can either ship nothing and be useless for nearly everyone, or ship everything and surprise users if they switch to the official builds and find out stuff is missing.

Nginx used to be as bad, but that's been fixed recently.

Personally Caddy is also not very useful for me, since I use a reverse proxy, and Caddy didn't seem very helpful there the last time I tried. Oh, and it would have been nice to be able to make it generate self-signed certificates for staging environments.

<comment><USER15> What problems did you have with reverse proxying?

The article says 0.9 can now generate self-signed certificates like so

        tls self_signed

</comment></comment></comment></comment><comment><USER16> I'm awesome to see Caddy come so far. We started using Caddy a little over a year ago, when we needed a replacement for nginx as a reverse proxy that could talk directly to mesos to figure out routing. At the time I rewrote the reverse proxy middleware to get the functionality I needed, but we ended up maintaining our own fork (which is now widely behind), because we needed our own plugins (and a mesos reverse proxy didn't seem useful enough to integrate into caddy core), so its great to see first class support for plugins.

<comment><USER17> Thank you for your work on the proxy middleware, Nimi! Hopefully in the future we can get it to the point where you won't have to go to all the work to maintain a fork.

<comment><USER16> I think the current Caddy plugins satisfies that - for us its more "if it ain't broke, don't fix it".

</comment></comment></comment><comment><USER18> Can Caddy work as a reverse proxy to other backend services? And if so, can I use QUIC for the backend and plain TCP for the front-end? Would that give me any benefit?

<comment><USER6> \- Can Caddy work as a reverse proxy to other backend services?

Yes. Use this in your Caddyfile:

      proxy /api 10.20.30.40:8080

\- And if so, can I use QUIC for the backend

No, QUIC is not supported at the moment: [https://caddyserver.com/blog/implementing-http2-isnt- trivial](https://caddyserver.com/blog/implementing-http2-isnt-trivial)

\- and plain TCP for the front-end?

Yes, if you mean HTTP/1.x. Also, you can serve static files from the proxy itself. Everything not mentioned in explicit "proxy" directive would be served from local files in the same directory as Caddifile.

<comment><USER6> Oops, QUIC is now supported:

[https://github.com/mholt/caddy/releases/tag/v0.9.0](https://github.com/mholt/caddy/releases/tag/v0.9.0)

</comment></comment></comment><comment><USER19> API Bootstrapping

What if you could slap something like Caddy in front of any API and provide authentication, analytics even billing out of the box.

      - Rate limiting
      - <USER2>
      - Authentication and Authorization using OAuth or JWT
      - Analytics/Metrics
      - Geo Location
      - <USER3>
      - HTTP2?
      - Image optimization
      - Content minification
      - <USER4>
      - Signaling Slack/Push/SMS
      - Caching through cloud storage S3, BlackBlaze B2
      - <USER5>

<comment><USER20> GoKit does that ([http://gokit.io](http://gokit.io)) – I heard about it on the changeling podcast [1]. Really cool set of scripts. Haven't used it personally though. There's also a changelog episode about Caddy [2], although I'm sure some of that will be outdated starting today.

[1] [https://changelog.com/163/](https://changelog.com/163/)

[2] [https://changelog.com/179/](https://changelog.com/179/)

<comment><USER21> GoKit looks awesome!

</comment></comment></comment><comment><USER22> When I went to use Caddy (because I love the idea of it), I was disappointed to find that there was no yum repo.

Of course, this makes sense because you have to compile the features in.

But, it would still be nice to have deployment automate-able. Maybe an Ansible role that combines the feature list you need and downloads it via an API.

It's the major, and only reason I quit and went back to nginx.

<comment><USER23> Why not create your own package? Can do a basic one with fpm

<comment><USER24> Because then you also need to host a feed, and keep it updated when new releases become available, and keep it updated when new plugin releases become available, and ensure the feed stays up, and maintain patches, and maintain required dependencies. All the things that package maintainers (thank you!) do for the ecosystem. Unless there's substantial gain why not just stick with Nginx?

For what it's worth though FPM is awesome, and has made my life better a number of times. If you have to have software that isn't packaged and you aren't familiar with packaging, look into FPM.

[https://github.com/jordansissel/fpm](https://github.com/jordansissel/fpm)

<comment><USER23> What dependencies? This is statically compiled go.

Binaries are available, automating a download and wrapping into a package with FPM is not that much effort.

<comment><USER24> Right, it's not a tonne of work if you _need_ it or really _want_ it. But it's still extra effort to move away from a supported package provided by the package management software. Not providing repos means you lose the users who might want to play around with it but don't have any packaging experience. This shouldn't be very controversial.

</comment></comment></comment></comment></comment><comment><USER25> How does this compare to NGINX? Especially around performance and security?

<comment><USER26> NGINX is a battle tested C high performances general purpose server, while Caddy looks more like a collection of diverse Go libraries bundled together. I don't see a lot of protocols implemented by Caddy itself. There is also the question of Go garbage collector performance and its over head, there is no GC pauses with C.

This is a great project though, the author is young and talented.

<comment><USER27> > There is also the question of Go garbage collector performance and its over > head, there is no GC pauses with C.

Malloc/free are not cheap either.

<comment><USER26> > Malloc/free are not cheap either.

They are still way cheaper than GC pauses in Go.

<comment><USER28> The Go GC with 1.5+ (and especially the work going on currently for 1.7) makes it all but unnoticeable for the majority of non-soft realtime (think HFT) systems:

[https://talks.golang.org/2015/go-gc.pdf](https://talks.golang.org/2015/go- gc.pdf)

For 99% of users, it is simply not noticeable anymore. Also note that I've worked at said HFT nanosecond latency types of firms the past 9 or so years.

</comment></comment></comment></comment></comment><comment><USER29> I just replaced nginx with caddy on a staging server. Works flawlessly, very easy to install. The docs could use some improvement though, especially in the way of examples.

</comment><comment><USER30> Can I use Caddy to provide a single point of authentication for multiple apps when acting as a reverse proxy?

So a request to a protected resource needs to be authenticated if not then redirect to a URL (login form).

If login is successful then a token is provided which can be used for authentication.

If a request is authenticated successfully then it can proxy to the resource.

</comment><comment><USER31> The static site generation was actually really cool, but I get the direction they're going with being a wrapper around secure web services.

</comment><comment><USER32> Curious if there's a plugin yet for adding caching headers to static assets?

<comment> stp-ip No plugin for only caching headers, but you can do that easily using the headers plugin or headers_downstream within the proxy plugin.

As an example:

          header / Cache-Control "no-cache, max-age=86400"

          header /images/ Cache-Control "max-age=86400"

          header /css/ Cache-Control "max-age=604800"

          header /fonts/ Cache-Control "max-age=604800"

          header /icons/ Cache-Control "max-age=604800"

If you want to add the header only to static assets that can be done, but is a bit harder.

</comment></comment><comment><USER33> Is anybody using Caddy on Windows? I use it on OS X via Laravel Valet which is excellent but I am looking for a replacement WAMP stack.</comment>


Show HN: Launched my side project: Goalfinch - <AUTHOR>

http://goalfinch.com
I had the idea for Goalfinch while reading an article here on Hacker News about economic incentives and how effective they are. It got me thinking: What if there were an easy way to set up economic incentives for the goals I have in my own life?
A few months later, after working on it off and on in my spare hours, it's ready for prime time.
With Goalfinch, you define a goal and make a contribution of cash that acts as an incentive for you to complete the goal. Your Facebook friends confirm whether or not you've accomplished it. If you succeed before your deadline, you get the cash back. If you fail, it gets donated to the charity of your choice. The combination of money on the line and your friends breathing down your neck makes for a very powerful motivator.
It's a pretty simple idea that could go in many different directions, but I wanted to share it with this community in its first, fledgling stages. Please let me know what you think!
http://goalfinch.com <comment><USER2> Nice, this perhaps has some very interesting implications for healthcare ! ?

If I may offer three thoughts:

First, as I understand your model, you're taking 15% of the unrealized goal funds to pay for 100% of the transaction fees. This seems off in that the only way you benefit financially is by people NOT completing their goals. Hardly the point of your project. Why not take a "success fee" for playing an active role in helping people achieve their goals ?

Second, someone mentioned trust, and while this suggestion is probably not the ultimate solution, I would urge you to consider adding your personal profile(s) and picture(s). This would at least give people a human element to connect with. Similarly, the inclusion of "Gain, LLC" is slightly confusing, as well as perhaps lends to the possible interpretation that you are the only one gaining from the transaction.

Third, stickiness & ticklers... is there something you can do to gently remind people of their goals and / or get them coming back to update progress ? ?

Hope those help...

</comment><comment><USER3> It looks neat, though I'd worry about being gypped out of my money:

1\. I don't know your or your site from Adam (no offense intended, honestly) and your site hasn't been around long enough to have a rep. There aren't any "trust markers" around to help me decide whether or not to trust you with my money.

2\. I'd worry about, for example, some of my facebook friends not responding in a timely fashion or forgetting to do it, and the FAQ makes it sound like one person not responding would prevent me from getting my money back.

<comment><AUTHOR> Yeah, I totally understand. I'm actively looking for ways to increase the level of trustworthiness and to make people feel confident that I won't take the money and run.

<comment><USER4> Wouldn't you be doing the same thing if you were running a scam?

</comment></comment></comment><comment><AUTHOR> Clickable: <http://goalfinch.com>

</comment><comment><USER5> One suggestion: goal URLs should use a salted hash key, so that they aren't so easily guessed. Alternatively, implement some kind of access control so that you can only see goals you are a party to. Otherwise, seems great, I'm trying it out!

</comment><comment><USER6> Cf. <http://www.stickk.com/>

<comment><USER7> What does one do if there is an entrenched competitor? Theoretically there is room for more than one right? I haven't heard of stickk.com. It'd be interesting to see what OP does with this.

</comment></comment><comment><USER8> I did something like this a while back (<http://1week1project.com/tagged/week-9?chrono=1>). The hardest thing was trying to set a price, ie Should I pay myself $25 to schedule a dentist appointment?

It would be really cool if you were able have some better way to determine the payout for a certain goal. Perhaps you have your friends vote on it or something like that.

</comment><comment><USER9> It's a neat idea, and I like your simple design.

I'm really not crazy about the verifying with my Facebook friends though. I would feel much better about it if you told me what your app is going to do - is it going to send them an email, a Facebook message, post on their wall now? Basically, is it going to spam them?

Probably the best thing would be a screen shot of what you are going to send them.

<comment><AUTHOR> Good call. There's a screenshot of the notification they receive on the next page, but I just put in a disclaimer about never spamming them or posting on their walls.

<comment><USER9> Cool. Another thing I noticed is that I didn't go through and actually pick anybody for step 2, and it didn't stop me until I put in a dollar value for step 3. Maybe it should validate right after step 2?

</comment></comment></comment><comment><USER7> I can think of some pretty ironic goal/charities:

Lose 10 pounds or donate 10$ to heart disease research.

</comment><comment><USER10> Incorporate twitter login or some other OpenID provider.

</comment><comment><USER11> cool idea. good luck!

</comment><comment><USER12> It's so exciting to see people launching their new sites everyday!

Good Luck.</comment>


LLVM merges machine function splitter for reduction in TLB misses - <AUTHOR> https://lists.llvm.org/pipermail/llvm-dev/2020-August/144012.html <comment><USER2> In their comparisons they explain that the existing Hot Cold Split creates new functions for the cold parts which brings overheads due to calling conventions and exception handling. Their new method avoids that by using simple jumps.

I wish compilers were able to optimize functions boundaries for visible but not inlined better so they could optimize those function call overheads away automatically. There is no reason for a compiler to limit itself to the system ABI for completely internal functions.

Besides leaving values in the registers they are already in instead of moving them to where the ABI says they should be, this could enable passing C++ objects such as std::unique_ptr in registers where the current ABI forbids this. Or to eliminate nop destructors for objects that are always moved from in the called functions.

In general, I think compilers should see function boundaries in the source code as a mere hint when it comes to code generation just like they already do with the register keyword.

Is there any existing compiler work to optimize function calls where the implementation and all uses are visible in the translation unit?

<comment><USER3> > There is no reason for a compiler to limit itself to the system ABI for > completely internal functions.

As far as I understand it, this limitation is also the only thing preventing tail-call elimination in C/C++. Tail-recursive functions are essentially the same as 'while' loops (execute some instructions then conditionally go back to the start); they just have different scope and calling conventions. In particular, 'while' loops are always inline and can't be referenced from other functions, but tail-recursive functions can. Hence compilers can apply more aggressive optimisations to 'while' loops, e.g. re-using the same stack frame and iterating with a conditional jump.

However, as you say, functions-as-subroutines don't necessarily need to coincide with functions-as-interface. Tail-recursive functions which are only used internally can also be optimised to re-use the same stack frame and iterate with a conditional jump. If such functions are _also_ exposed in the interface, it's pretty trivial to expose a dummy entry point which invokes the optimised version (if we want to); although cross-unit tail calls wouldn't be eliminated in that case.

Of course, this is more useful than just writing 'while' loops in a different style (although I personally prefer recursion [https://news.ycombinator.com/item?id=11150346](https://news.ycombinator.com/item?id=11150346) ), since tail calls don't have to be recursive: we can split our code up into modular, composable, self-contained functions without having to worry about stack usage (or code bloat caused by inlining into multiple locations).

<comment><USER4> >As far as I understand it, this limitation is also the only thing preventing tail-call elimination in C/C++.

At the risk of introducing a tangent, can someone explain how compilers _detect_ tail recursion? This is still a complete mystery to me.

<comment><USER5> What part of the detection is giving you trouble? Detecting whether a call is recursive, or whether it is a tail call that can be optimized? The first part is relatively easy, you typically have some sort of data structure representing calls and their targets, and you know what function you're currently compiling. If the function you're compiling is the same as a call's target, you have recursion.

LLVM's code is at [https://llvm.org/doxygen/TailRecursionElimination_8cpp_sourc...](https://llvm.org/doxygen/TailRecursionElimination_8cpp_source.html)

The core of this detection is in findTRECandidate. It iterates backwards over a basic block, looking for call instructions whose call target is the current function F:

        CallInst *CI = nullptr;
        BasicBlock::iterator BBI(TI);
        while (true) {
          CI = dyn_cast<CallInst>(BBI);
          if (CI && CI->getCalledFunction() == &F)
            break;

          if (BBI == BB->begin())
            return nullptr;          // Didn't find a potential tail call.
          --BBI;
        }

The harder part is detecting whether calls are in fact tail calls that you can replace by jumps. There are all sorts of special cases, like whether alloca() might be called by the function.

<comment><USER4> Sorry, I should have been more precise: I was referring to detecting that a function is _tail_ recursive.

(Yours is still a helpful explanation, though -- thanks!)

<comment><USER6> I can't say how LLVM does it but in a compiler I built I detected tail recursion by scanning the IR and if the value of a recursive call (ie: call to self) was immediately returned it was considered a candidate for TCE. If the value was consumed by the parent, it wasn't.

</comment></comment></comment></comment></comment></comment><comment><USER7> The post on llvm-dev is ever so much more interesting.

[https://lists.llvm.org/pipermail/llvm- dev/2020-August/144012...](https://lists.llvm.org/pipermail/llvm- dev/2020-August/144012.html)

<comment><USER8> The llvm-dev google group retains the formatting of the original email and is slightly easier to read though it requires a gmail login.

[https://groups.google.com/g/llvm-dev/c/RUegaMg- iqc/m/VFyV9cX...](https://groups.google.com/g/llvm-dev/c/RUegaMg- iqc/m/VFyV9cX4BQAJ)

<comment><USER9> > requires a gmail login

[https://archive.is/pqLgW](https://archive.is/pqLgW)

<comment><USER10> This link + Safari Reader Mode is good

</comment></comment></comment></comment><comment><USER11> > Google engineers found a 2.33% runtime improvement with a ~32% reduction in > iTLB and sTLB misses

Not bad. Presumably this will benefit every compiler that uses LLVM, not just Clang.

<comment><USER12> Or at least any that supports gathering and utilizing profiling information. Last time I checked, that didn't include Rust yet for instance, but my information could be out of date there.

<comment><USER13> rustc does support PGO, but I don't know how mature the support is. [https://doc.rust-lang.org/rustc/profile-guided- optimization....](https://doc.rust-lang.org/rustc/profile-guided- optimization.html)

<comment><USER14> Can I create profile data by running the instrumented binaries through testcases? Perhaps integration test cases which represent typical end to end functionality of my application.

<comment><USER15> Unit tests are a bad fit, you need to run a test that is representative for an actual work load.

A unit test that tests code that's cold in practice would make it look like hot code, and be counter productive.

</comment></comment></comment></comment></comment><comment><USER16> Note that LLVM has already had a function outliner; you may have seen these paths already if you've ever looked inside a binary on macOS and noticed * .cold. * functions, which is the unlikely-to-execute code cut out from the function they came from. This appears to be an improvement on that effort.

<comment><USER17> Right. The improvement that this work brings is that it performs the function split very late and at a low level.

Basically, while the previous outliner split a function into two functions (the hot one literally calling the cold one as needed) this new thing takes a single function and splits it into two parts connected to each other by jumps. The cold part of the function isn't really a function --- it's just a group of basic blocks that happen to be located far away from the other group of basic blocks.

By avoiding the call into the cold function and the return to the hot function, the generated code can be smaller and more register-efficient.

<comment><USER18> Might be confusing to debuggers if the address-space range of a single function is discontiguous. Does the cold portion get an independent symbol with derived name, like, e.g., "Blocks?"

<comment><USER17> Yes --- the collection of cold basic blocks gets named "<origfunc>.cold". But it's nevertheless not really an independent function from a code POV.

</comment></comment></comment></comment><comment><USER19> FYI, this requires profile data to do the splitting. Yet another reason to do PGO!

<comment><USER20> For many use-cases FDO ("feedback-driven") can be more convenient and sometimes mkre effective than PGO ("profile-driven").

The difference is sampling prod vs sampling separately in test. The arguments for FDO:

\- Prod behaviour/data is always "representative", whereas synthetic or recorded data can go out of date quickly.

-PGO test fixtures can contain sensitive user data. Instrumenting production processes doesn't put data in more places.

The benefits of both are huge though. The rule of thumb I've seen is a 20% improvement for FDO over -O3.

<comment><USER21> I'm interested in reading some more on this concept, The Wikipedia, which usually my first stop for a broad overview and maybe some linked research, seems to suggest that profile directed/guided and feedback guided are the same thing. Is there anywhere I can read about the varying approaches?

<comment><USER7> They are the same thing. The GP makes a distinction which does not exist. Witness the fact that two different compilers refer to the exact same feedback technique as either AutoFDO or SamplePGO.

<comment><USER20> Ah, I definitely worked in a place where that distinction in terminology was used, but maybe it isn't widespread. In any case, whatever you call either one of them, sampling from production processes can have benefits over sampling from synthetic workloads.

<comment><USER22> Surely that's a given?

It's literally sampling from a representative workload (production) vs a non- representative one (anything synthetic).

<comment><USER20> Maybe so. I think it was a novel idea to me because my intuition around profiling was formed with an assumption of delivering binaries to users, and not running server processes. (It's probably also a pre-internet bias of thinking it would be hard to _get_ prod data, whereas profiling data from generated in a horrible enormous compile&run&profile&recompile process at least doesn't need to "go" anywhere.

</comment></comment></comment></comment></comment></comment></comment><comment><USER23> It always surprises me how many people are familiar with LLVM internals. Just looking at the 60 unique commenters at the time of posting this is blowing my mind.

</comment><comment><USER24> > We find that most functions 5 KiB or larger have inlined children more than > 10 layers deep

Ok, I would not have expected that.

<comment><USER25> I wouldn't have expected any functions to be 5KiB or larger. That seems like a lot of assembly to me, and so it makes sense to me that these functions would be "accidentally" generated by inlining.

I'm curious what percent of functions are this large?

<comment><USER26> I've seen plenty of c/c++/java functions that exceeded 200 lines of high level code. It seems reasonable to me that such a function would be 5k bytes of machine code, especially on a 64-bit architecture.

Not that such functions are the right way to structure your program...

<comment><USER2> > especially on a 64-bit architecture

Pointer size has little impact on code size. amd64 code can even be smaller than x86 in some cases.

</comment></comment></comment></comment><comment><USER27> This + multi-return (push multiple code addresses in stack frame) together mean I think we can just use Result/Either and never unwinding, and leave no performance behind.

<comment><USER28> It doesn't work in Rust, only Clang

<comment><USER27> Why? Other commenters were talking about PGO and saying Rust did support it.

</comment></comment></comment><comment><USER29> LLVM is one impressive (and scary) piece of technology.

<comment><USER30> FWIW this particular optimization has been in GCC for about 15 years, though it was only enabled by default in GCC 8. It's not rocket science.

<comment><USER31> Idk, not learning compiler theory is one of my regrets from school and this does seem like rocket science to me.

<comment><USER32> There are a ton of great books out there! If you're looking for a bit of the whole shebang, check out Compilers: Principles, Techniques, and Tools (aka, The Dragon Book). It's an older book, but a lot of what is described in there is still very relevant and good info. If you want a more high level overview at first, I'd recommend Crafting Interpreters [0] and Writing a Compiler/Interpreter in Go [1]. The latter two focus more on lexing, parsing, and intermediate code generation.

[0] [https://craftinginterpreters.com/](https://craftinginterpreters.com/) [1] [https://compilerbook.com/](https://compilerbook.com/)

<comment><USER31> I know I should get to it - maybe I should've done that during the COVID lockdown eh? Thanks for the links, I'll check them out.

</comment></comment></comment></comment></comment><comment><USER33> 2% better perf isn't anything to sneeze at but also not super drastic. Will be curious to see if this unlocks more optimizations over time.

I'm also curious if there's been any work to organize code layout to make it more efficient to page stuff out efficiently to reduce memory pressure (so that you're using all code in the pages you are bringing in) & reduce paging thrash (you're not evicting a code page only to bring it back for a few hundred bytes).

<comment><USER34> Given the greatly improved TLB hit rate, I sort of wonder if the test isn't abusing the code enough. Does this change the inflection point where throughput falls from trying to run too many tasks in parallel or sequentially? 2% response time won't do much, but 10% higher peak load would change quite a few priorities on a lot of backlogs.

<comment><USER33> It's not too surprising to me. If TLB misses cost your program to run 6% slower, wouldn't you expect a 30% reduction in that to be a 2% overall improvement? Why would it be more? If you're surprised that TLB misses are not so costly, consider that cache locality and CPU prediction are largely going to hide the cost of misses (cache locality means the miss rate is low to begin with, prediction reduces the cost of a miss). TLBs are also super complex involving a few layers of caching (TLB look aside, L1 cache of your TLB table, L2 cache, L3 and then RAM).

</comment></comment></comment><comment><USER35> So to use this new optimization pass you have to specify it explicitly with an additional command line flag instead of it simply being turned on as an ordinary part of PGO?

It seems like most people who just want to squeeze the last drop of speed out of their code will probably never become aware of it then unless they are specifically seeking it out

<comment><USER36> It's an experimental feature. If it works well for a while, it may become part of the default. But it should definitely not be forced on everyone if it's not yet sure how well it works.

</comment></comment><comment><USER37> One issue with PGO is you are optimizing for the particular subset of use cases which are profiled, on the exact machine you profile on. The 2% quoted improvement will not necessarily generalize across all use cases for the software and all machines it runs on. In fact, you may often be taking that 2% or more away from other use cases.

<comment><USER38> > One issue with PGO is you are optimizing for the particular subset of use > cases which are profiled, on the exact machine you profile on.

The exact machine part is not true. There's nothing about this particular optimization that's machine specific - e.g. as the original post explains, this optimization gives performance boost on Intel and AMD, on Intel due to reduction in iTLB misses, and on AMD due to reduction in L1 and L2 icache misses. i.e. this kind of "working-set" reduction translates to any platform.

> In fact, you may often be taking that 2% or more away from other use cases.

In general, it is correct that profile-guided optimization can theoretically reduce performance, as some of the aggressive optimizations are only done with profile because of inherent trade-off the optimization has (e.g. aggressive inlining which can be detrimental for the performance if hot functions are entirely different).

However, empirically this is not true in most cases, unless you picked really bad training input, _and_ your code has extremely different behavior under different input. Moreover, nowadays with sampled profile, which you can collect from the real, production runs, it's extremely unlikely for this to happen.

</comment></comment><comment><USER37> I take it this is a form of profiler guided optimization? Does MSVC already do this during its PGO? It seems like an obvious thing to do.

<comment><USER39> MSVC does have this optimization. It has 3 sections: 'live', 'sick' (referenced, but uncommon), 'dead' (unreferenced in the profile).

<comment><USER7> Yes, this is a pretty old technique. There were papers about hot/cold function splits based on profile data as early as 1996.

<comment><USER40> The technique itself isn't new in clang either. This is about a new implementation of it, where the difference to the existing implementation is that this happens later in the process (it's deferred to the machine-specific code generation phase, whereas the existing implementation happens in the middle-end and is target-agnostic).

<comment><USER33> The other major piece is that the hot-cold split is more efficient. Rather than thunking out the cold code via a function call it just jumps to the basic block, making it a more efficient approach (no register spilling and function call overhead)

<comment><USER40> The function call overhead itself is irrelevant, because by definition these blocks are cold. The saving/restoring of callee-clobbered registers does affect the code size of the hot function though, so that's important.

<comment><USER41> Blocks are cold by an imprecise measurement.

Decreasing the downside means you can apply the hopefully-optimisation more aggressively for more gain so I would expect it to matter.

</comment></comment></comment></comment></comment></comment></comment><comment><USER42> Google improving an Apple project. The high ground!</comment>