2,421 karma · joined February 21, 2007
jonolson at google dot com
Opinions are my own, not those of my employer.
It is not Java-specific, but it is common to a few specific Java frameworks as well as at least one of Microsoft's older frameworks (I forget which one).
The vast majority of frameworks (including most modern Java frameworks) do the sane thing and keep application state on the server side (often in a database, as you describe) and UI state on the browser side, which allows links and forms to work the way links are generally supposed to work.
It's common enough that it's been used as the title for a pop animated sitcom episode -- Archer (S2E2).
So you can assign a virtual function from any SR-IOV-capable NIC into a VM using common code, but what the guest sees inside the VM will still be an Intel, Mellanox, Chelsio, etc. device. Naturally they'll need a driver for that device.
If your fleet includes NICs from a variety of vendors, you'd never be able to live migrate VMs between hosts with different NIC models. Until recently, no vendor I knew of included the relevant serialization and deserialization functionality to allow for live migration at all.
That said, SR-IOV isn't a BAD option if you don't care about live migration of VMs over a lifespan potentially longer than the underlying hardware platform. It's a good option if you can live with host-hardware-specific drivers in your guests, you're willing to standardize on a specific NIC as host hardware for the fleet where you'll be running VMs, and you're willing to deal with the resource commitment it requires to deliver on its performance promises.
When they say "virtio-net" there they mean virtio-net inside qemu with vhost servicing the queues on the host side (note, we don't use vhost in GCE -- our device models live in a proprietary hypervisor that's designed to play nicely with Google's production infrastructure). One could just as easily expose what looked like an Intel VF to the guest and service it in the same manner (although there are good reasons not to).
One could also build a physical NIC that exposed virtual functions offering register layouts equivalent to VIRTIOs PCI BARs and used the VIRTIO queue format. If you assigned those into a guest, you'd be doing SR-IOV, but with a virtio-net NIC as seen by the guest. It also likely wouldn't perform as well as a software implementation (in its current form VIRTIO has a lot of serializing dependent loads which make it inefficient to implement over PCIe). There's some ongoing work upstream aimed at a more efficient queue format.
So, yeah, "it depends" is about the best you can do. SR-IOV really just says you're taking advantage of some features of PCI that allow differentiated address spaces in the IOMMU for a single device and (on modern CPUs) interrupt routing to actively running VCPUs without requiring a hop through the host kernel. The former is handy if you want the NIC to be able to cheaply use guest physical addresses (although the IOMMU isn't free either); the latter doesn't matter if the guest is running a poll-mode driver that masks interrupts, nor does it matter if the target VCPU isn't actively running.
Speaking from (decently informed) personal opinion here--
I see SR-IOV as a means to achieving certain networking characteristics, but one that historically didn't play particularly nicely with live migration (among other things), and one that locks you into particular silicon vendors, etc. It's a bit unfortunate that SR-IOV is often assumed as a prerequisite for high throughput, low latency, low jitter networking. On its own it doesn't guarantee any of those things (you're still beholden to the VCPU scheduler, if nothing else, and there's a lot of 'else'), and it's also not the only way to achieve those things. In particular there are a lot of ways to dedicate hardware to I/O service they aren't SR-IOV
In terms of RDMA and bypass messaging, I agree there can be substantial advantages to offloading transport layer message processing from VMs. Regrettably, I can't say anything more on the subject today.
(I lead the team that owns the virtual NICs exposed to guests in GCE)
Given that, I could easily see how "feeling" that you'd hit the right digit (give or take) might be faster than focussing on visually actually hitting the right digits.
Not claiming any responsibility for it, naturally, simply observing that it had happened.
Having recently done some coding in Swift to implement a little toy Hypervisor, I sorely missed these annotations. By and large the errors they catch are ones I'd be embarrassed to have pointed out in a code review; I don't mind nearly so much when the compiler catches me without my mutex locked.
If you have many threads each doing small amounts of work before blocking, the kernel will happily switch in another runnable thread when the current thread blocks. This is common in workloads that service network IO using a 1:1 thread:client model.
It can absolutely be more efficient to retire work for multiple clients from a single thread. Your last paragraph ignores this. It also forgets that in addition to prioritization there is multi-core load balancing to deal with. That can leave runnable threads stranded for whatever the LB interval is (which is independent of the overall scheduler quantum), while a concurrent service queue would allow steady service of all clients from all workers (that said, I actually prefer the siloed model in most cases).
A lot of the promise of GCE and GCP generally come from on-demand scalability, autoscaling, serverless, etc. Those become much more relevant as projects scale from a small set of fairly static resource requirements to larger and more dynamic usage. Take a hypothetical online retailer -- they might need few hundred cores at night while their users are asleep, a few thousand during the day, and tens of thousands on, say, black Friday. GCE lets you do that kind of scaling as-needed rather than having to provision far in advance (although there are pricing advantages if you can commit to cores and RAM over the long term).
(note: I work on GCE)
(For "Local SSD" the IOPS are a function of the number of devices you attach)
(also, should've mentioned in original post just for clarity -- I work for Google, but do not know any of the details of this work)
PDF has the convenient property that you can inject arbitrary bogus data into the middle of it with a constant head and tail and it will still be valid. The tail of the file contains a trailer that points to the dictionary that describes where all of the resources in the file are located. The entire file need not be covered by the dictionary (and typically won't be for PDFs that have gone through several rounds of annotation/modification). This leaves the opportunity "dead chunks" that can be modified arbitrarily without changing the rendered result.
Asking as a Googler who occasionally gets to dream up a neat trick here or there (and leads a team of pretty clever people, too!).
If you're going to add moveonly types with destructors, though, it seems strongly desirable to give them (or at least making available) lexical RAII semantics.
That said, having that be optional opt-in behavior could be valuable from a compiler optimization freedom perspective.
It's not a blocking semaphore -- we explicitly don't want it to block after the third call. The example was an entirely artificial construction to get (a) an early return and (b) a use for locking for thread safety (you could of course also do it with just an opportunistic CAS loop). That said, yes you could build it with a semaphore that included tryDown() in its contract.
My day job is working on the VMM that backs Google Compute Engine. Thread hops (it's the wakeups, really) have a measurable and for some workloads substantial performance and efficiency penalty. This makes the use of GCD and similar technologies untenable (while GCD could be written such that dispatch queues handle synchronous dispatches on the calling thread, the docs do not guarantee those semantics iirc). To really drive the point home Hypervisor.framework requires that some calls be made from specific threads, so taking on a similar project to my day job in Swift would really absolutely require knowing details about execution context.
I've been building a little toy VMM, mostly as an opportunity to learn Swift outside of work, so my concerns aren't entirely hypothetical (for a null or nearly-null operation like fizzle GCD is up to a hundred times slower in Swift today than a spinlock lock/unlock with warm caches). This still puts dispatch in the realm of microseconds, though, so for many workloads it's fine. It's too long (and way too many cycles spent in actual compute) for things like dispatching network packets or flash storage IOs, though, particularly if overall cycle budget is a concern.
https://github.com/apple/swift/blob/master/docs/OwnershipMan...
> Swift is permitted to destroy a value (and thus call deinit) at any time between its last use and its formal point of destruction. The exact definition of "use" for the purposes of this definition is not yet fully decided.
For things like scoped lockables the last "use" must be well defined with respect to the termination of the scope. Early deinit means you're still unable to build something like C++'s std::lock_guard (http://en.cppreference.com/w/cpp/thread/lock_guard).
Consider:
// dwizzles can be fizzled up to three times, but no more.
class dwizzle {
public:
dwizzle() : count_(0) {}
void fizzle() {
std::lock_guard lock(&mutex_);
if (count_ >= 3) return;
++count_;
}
private:
std::mutex mutex_;
int count_ = 0;
};
Obviously a silly toy, but the point is that we acquire the lock, we must hold it until the end of the scope for correctness, and we want to ensure it's dropped on early returns.I hope any formal proposal coming out of this has a sufficiently strict definition of "use" (or provides opt-in tools for building structs that restrict the definition appropriately) to allow such constructions. It's much nicer than having to always type something like:
mutex.lock()
defer {
mutex.unlock()
}
(apologies for any inconsistency in my C++ above -- the codebase I routinely work in has its own mutex type and an equivalent scoped lockable -- I tried to adopt the more standard version for universality's sake).Also, modern GVC is fucking amazing.
My preferred concrete example, simply because of how staggeringly effective tolerating hypocrisy was at getting a resoundingly unpopular law to become the law of the land is American Prohibition. During the lead-up to prohibition in the United States one of the most successful lobbyists was a man named Wayne Wheeler of the Anti-Saloon League. He would work with or endorse any candidate that supported a dry agenda, and he'd work to replace those that didn't with those that did. This included candidates who were, themselves, barely-functional alcoholics. They would drink while meeting with him (he himself was truly a teetotaler as far as we know) while discussing the very legislation that would make acquiring alcohol illegal. He took it all in stride as long as they voted the right way. Despite the perceived success of the wets in attaching a 7-year limit on time-to-ratification for the 18th amendment, it passed the required number of state houses in less than two years.
For a more modern example I direct you to Republican's willingness to re-elect "family values" candidates who support and push through anti-LGBTQ legislation but who have themselves been caught in flagrante delicto. I find such laws reprehensible, but I cannot deny the effectiveness of the right in passing them, in part due to a willingness to tolerate effective but hypocritical legislators.
In terms of where I believe a failure to tolerate hypocrisy has resulted in net loses for progressive causes, I'd point to politicians with strongly progressive voting histories are pilloried and their political careers are summarily executed because they turn out to be corrupt, sexist, racist, homophobic, etc. If their voting history and the legacy they're leaving behind is a progressive one (and stays that way), who cares if they're only pursuing it because they know it will get them re-elected? Unless you can find a candidate who will produce a better net effect, stick with the flawed bigot.
Concretely, take Hillary Clinton after the primaries[0]. I saw it argued that she was a hypocrite for taking millions in speaking fees from big banks while talking about protecting the little guy. She may well be a hypocrite (and her banking voting history isn't great), but the platform she was running on and much of the rest of her voting history are solidly progressive. The number of votes lost due to perceived hypocrisy probably wouldn't have swayed that contest, but more broadly I see it in the same category of being idealistic to a fault.
Don't tolerate hypocrisy for hypocrisy's sake, but recognize when it's pragmatic to tolerate it to either move things in the correct direction or simply to limit how far they slide in the wrong direction.
An explicit part of their business plan is maximizing free cash flow (not profits).
I'm not sure what funding you think the company is getting from investors. Amazon's stock price could drop through the floor and the biggest issue the company itself would face is the departure of a workforce who take a significant chunk of their compensation in AMZN shares. Unless they're hoping to do another public stock offering the share price is mostly useful as a gauge on Jeff Bezos's net worth.
When the company does want outside funding, it hasn't turned to public stock offerings in recent years. Instead they've secured it by issuing corporate bonds[0]. THERE is somewhere they might have to worry, but as long as their credit rating stays high, they'll find plenty of institutional buyers. Their credit rating is maintained by people who understand that profitability has little to do with how well a large business is doing, and is sometimes an indication of failure to manage funds well (failing to employ depreciation appropriately to minimize tax liability in very successful years, etc.).
[0]:https://www.bloomberg.com/news/articles/2014-12-02/amazon-se...