HN user

physguy1123

221 karma

physguy11239@gmail.com

Posts0
Comments103
View on HN
No posts found.

When there's a stopped vehicle in the lane you're in, you can simply check for traffic in the next lane and switch lanes.

You're not restricted to the bike lane if there's an obstruction.

These comments proves my whole second point. If a car were to just park in the car lane because it felt like it, there would be outrage, tickets, and the car would get towed immediately. Nobody would say "no big deal, just change lanes". But when a biker says "I don't like using the street because it's dangerous", it's just dismissed like this.

You also ignore that bikers DO just change lanes into the street, which can be quite dangerous somewhere like New York. I don't know if you've ever ridden a bike in New York, but drivers, especially taxis, are at best ignorant of you and often antagonistic. There's a reason bike lanes exist in the first place, and it's because the car lanes are dangerous.

It's far easier to take responsibility for your own safety than to rely on others to do it for you

Imagine somebody saying this when a car driver complains about somebody else running a red light, or cutting them off in a lane - you would get laughed out of the room. But when drivers act dangerously towards a biker it's the biker who should be taking responsibility.

When bikers do all the terrible biker things like roll through stop signs, or "act like pedestrians", or roll to the front of the line, that IS taking our own safety into our hands by doing legally dubious things that make biking much safer, yet everybody hates that as well.

There's a reason why drivers of motor vehicles don't typically drive in the door zone.

Have you ever been in New York? Plenty of car lanes themselves are near the door zone, not to mention bike lanes themselves ARE the door zone usually.

I don't mean to be aggressive, but the endless victim blaming towards bicyclists gets really tiresome. I really wish that people who just dismiss these complaints out of hand would bike to work in NYC for just a week.

This doesn’t do anything when cars decide to park in your bike lane anyways, and your bike lane has maybe a foot clearance to traffic in the other side.

It’s also an interesting attitude, that cars are so much more important than bikes that it’s not car drivers who should check the road when opening their door, but bikers who should lose the 6 feet of street space near parked cars which is the only semi-safe place for bikes in New York

I can attest to the basic lock-free spsc queues being far faster than a basic spinlocking version of the same queue, on xeon-class X86 at least.

LOCK'ed instructions (one might use lock xchg or lock cmpxchg) perform a full memory barrier, which has quite a few performance implications if there are any outbound loads/stores. Further, if the cache line containing the spinlock is in anything except an exclusively-held state on the writing core (it will usually be on a different core or in a shared state), simply acquiring the lock will stall for ~25-30ns+.

On the other hand, a simply spsc lock-free queue can hit <10ns per message with a latency about equal to the core-core communication latency.

I'm not sure if I'm the target audience for this (low-latency trading), but here's my thought - code which would allocate in a fast path is a strict no-go for me, and this runs fairly close to that in a few regards:

It seems easy to accidentally make allocating code allocate by changing some variable names (b = fnc(a) - oops, allocation)

I would be extremely wary of trusting a compiler to realize what sort of allocations are optimizable and not - I already have problems with inlining decisions, poor code layout, etc in fairly optimized c++/rust code compiled by gcc+llvm.

Replace allocation with any other expensive work that duplicating a datastructure would result in, and you have the same story. I suspect many of the people that would be evaluating this compared to C/C++/Rust have similar performance concerns.

If you are in an environment where you can guarantee that a piece of code runs in bounded time (no interrupts, no faults, etc), then locks can actually be used in lock-free algorithms since code inside the lock will always be making forward progress and will exit in or before some deterministic time. If the lock is fair and there's a bounded number of threads accessing the lock, then it technically becomes wait-free under these conditions since time to completion is bounded by n_threads * task_time;

This environment only happens to exist in very specific and uncommon settings, so it's not a generally useful concept for lock-free programming. It's common in the linux kernel to see spinlocks taken in sections which have disabled all interrupts, for example, but this is not an environment that normal programs can live in.

In New York at least, constructions unions extract large amounts of money from the government. Some examples that come to mind:

  * Lots of construction employees are mandated by unions to stay around (crane greasers I believe are an example) even though these employees do no work, and then managers have to be hired to manage more employees, etc.
  * Sometimes employees are hired to do no work at all
  * Highly experienced employees will be given menial jobs like coffee-fetcher sort of deal, but get paid very highly for it due to their experience.
  * The MTA has no negotiating power, the unions and the construction contractors agree on a price and then give it to the MTA
Why is it like this? I don't know, one could imagine all sorts of corruption, political plays to get the construction vote, political games to avoid seeming anti-union, who knows.

If you're talking about the USA, this is incorrect. I actually work in the industry and know how this works

* One has to initiate an auction of the client order, at least in the USA - see https://www.sec.gov/rules/concept/34-49175.htm#P193_52817, specifically "Unlike internalization in the over-the-counter equity market, the options exchanges' rules permit a firm to trade with its own customer's order only after an auction in which other members of that market have an opportunity to participate in the trade at the proposed price or an improved price. This auction provides some assurance that the customer's order is executed at the best price any member in that market is willing to offer". In practice the placing firm will bid for the auction at that price, and non-competitive prices don't get posted since then the firm has to lose money.

* counterparty data is reported by the OCC so regardless of where the order was executed you will know who was the counterparty. It's fairly easy for IB to know whether Timber Hill executed an order, whether or not they intentionally routed it there.

Second, I actually have inside knowledge of a sort about how Timber Hill USA worked before getting purchased by Two Sigma, and they did not work with IB to take customer orders and weren't to happy when they did get customer orders that originated from IB, specifically because people then run around complaining that IB is up to spooky business internalizing with Timber Hill.

It is strictly not internalization, in fact, and as far as I know from friends working on retail at the new owner of Timber Hill IB and Timber Hill didn't ever cooperate on optimal routing strategies since Thomas Pterfry didn't want people loosing faith in IB routing. There are plenty of reasons why Timber Hill might win the trade:

  * They might be first in the queue on a price-time exchange, and so naturally get the order

  * They might be on a price-size exchange, and so get some of the fill simply by being present.

  * They probably participate in the auction process, and will naturally get some portion of orders that IB initiates
For what it's worth, Timber Hill USA was bought by Two Sigma ~1 year ago. It wasn't actually unprofitable as shown by public filings, but wasn't making much and Thomas Pterfry didn't want an illusion of conflict of interest.

If you're an HFT, you would much rather just pay for the order flow and not deal with all the shit that is retail (government, customers, all that shit). If you're some big retail firm, you're probably run by suits, way to beauracratic to run a difficult high-tech trading team, and any talent you got would get siphoned off to a good trading firm.

IEX's speed bump in the end simply allowed their special internal dpeg order type to pull slightly back when they saw adverse movements incoming, for many normal trades it's essentially an exchange that acts like it's a little farther away (longer latency) than it actually is with some dark order types which move weird.

It might simply just be that's the terms that Robinhood reached with the firms? Paying 0.2c/share and giving 0.2c/share price improvement is fairly similar from the perspective of a market maker as just paying 0.4c/share, and Robinhood might be funding themselves by having firms only compete on payment for orders and not on price improvement.

On a more meta level, my firm suspects that Citadel is trying very hard to price other players out of the market even if it's at the cost of their current profitability, so they might be driving up the terms of newly minted deals. I don't work on the retail desk so I don't know.

Timber Hill did not participate in the retail business to avoid conflict of interests with IB.

For what it's worth, one can't internalize options orders in the same way one can equity orders, purchased options flow must make it to the market. I'm not familiar with the history of this decision but I suspect it's since options are less liquid and have higher spreads, so internalization would get a much worse deal than say auctions. You can rebates from certain exchanges for initiating auctions on them, and can selectively initiate auctions on exchanges which benefit you more, but options orders themselves make it to the market

In this specific case, it means that retail flow is much less likely to immediately move the market than flow from an informed (knows the market will move soon) or large (will trade so much that it will move the market) player, and is much more valuable to market makers who try to capture the spread on that order (and usually improve it) and hedge/trade out of that risk relatively soon.

On x86, push/pop have dedicated hardware optimizations known as the stack engine which perform most of the rsp increments/decrements and passes those offsets into the decoder, instead of using executions slots on them. push/pop are also much smaller than the corresponding mov/add instructions.

It's much more optimal to use a series of push/pops for smaller operations like saving registers before a call than to manually adjust and store onto the stack.

While technically this is still incrementing/decrementing a register and storing, the amount of isa/hardware support for such things clearly demonstrates that the x86 isa and modern x86 hardware gives special treatment to the stack.

even though by definition people are overvaluing whatever is in the bucket

By that do you mean that etfs which people might buy are overvalued compared to the stocks which compose the etf? Or that overinvesting in the etf results in the stocks getting overvalued?

Because as somebody that works on etf market-making, no liquid etf is trading outside of a reasonable fair-value spread based on the underlying components, unless you count situations where markets for the underlyings are closed so there's no exact fair value.

Individual investors don't need to pick single stocks to benefit from growth. These companies also don't have a presence in various etfs and mutual funds that people can invest in, and it's not unreasonable to think that a wider selection of say small-cap growth companies might make for a better selection of small-cap stocks to put in an index.

This is great benchmark of the fundamental problems with say Java - the code itself is fairly simple and the JITs probably generate optimal code given their constraints, but the performance problems clearly show that the GC and pointer chasing really hinder your performance.

If you add in cases where simd, software prefetching, or memory access batching help, the difference will only grow.

In my experience, writing java (or groovy here) in c++ results in horribly slow code which the jvm runs circles around, and it sounds like that's the problem your employee ran into.

But for all the applications where the high performance code is in niches at the edge and there simply aren't resources or expertise to fully tune the native implementation

It's interesting you say this, because in my experience it's the JVM which requires absurd amounts of tuning and native programs which are much more consistent. The proper and easier way that native programs are written lends itself to fairly respectable performance, mostly because the object and stack model of say C or C++ is so much friendlier to the CPU than in most dynamic languages.

In general, for all that I hear statements along this line, I've only twice seen code to back it up, and the C was so de-optimized from the OCaml version that I suspect it was intentional - the author (same for each) was a consultant for functional languages, and in one case switched the C inner loop to use indirect calls for every iteration and in the other switched the hash function between the C and functional comparison.

SIMD, multicore, and caches don't just magically happen with better compilers. SIMD requires very specific memory access and computation patterns, and cache-friendly code has similar restrictions. The features of even basic javascript fly in the face of code being simd and cache friendly except for the most trivial programs.

Automagically parallelizing general serial code is something that isn't feasible on any hardware similar to modern cpus and probably will never mesh well with fast single-threaded performance (communication and synchronization in hardware is HARD)

There's a distinction to be made between many different players in 'hft'. You have market makers, latency arb, plain old short-term quant trading which all provide different sorts of 'economic value. Most players are running a mix of some to all of these strategies - for example, in options, fast trading on spot moves is really some weird mix of everything from latency arb to market-making to long-term option pricing.

One could argue that pure latency arb (what flash boys portray as hft) is fairly useless since it's just trying to catch stale quotes that market makers would move otherwise, but that's a very small portion of the industry.

You should try maintaining 4 independent sum variables and summing after the loop so there's no serializing dependency at all. Such a transformation in microbenchmarks is a fun trick to show the power of a proper OOO engine with pipelined instruction units. Assuming no memory problems, one should be able use issue-width*instruction latency independent sum streams without spending more time in the hot loop.

For what it's worth, the vmovdqa only has a 4-wide issue width if it is moving between registers, the memory load has a 2-wide issue width. Floating point adders themselves only have a 1-2 wide issue widths depending on your hardware so it doesn't really matter.

It's theoretically possible and has always been for somebody to see order execution in progress and trade ahead of it. In practice, that's frequently just a side effect of somebody being so slow that their actions trigger quant algorithms, it's not a super profitable game trying to latency arb proper market sweeps anymore (not to say latency is not important in but, but it's usually for other reasons)

Yes, I work in the industry. Flash boys is misleading garbage, it's a long form advertisement for IEX.

What a broker does has nothing to do with how market orders work. The strategy you're describing also doesn't really work because any respectable broker is sweeping all of the exchanges at once - the regulations considered this possibility and allowed this behavior. Also, many of the liquid symbols have single cent spreads making this strategy impossible.