Anyone can put up a web page, and Javascript and PHP have a large footprint there. (I guess Java, on the enterprise server side?) It's not hard to imagine there's lots of folks that have to deal with these languages as part of their larger duties, but aren't really trained as programmers in any traditional sense. That could fuel a bunch of StackOverflow traffic for sure...
Whichever ranking you look at will be skewed by the methodology. It feels like web-oriented languages are overemphasized in this cut.
Of course, my own worldview is skewed, too. I deal more with low-level hardware, OS interactions, etc. You won't find a lick of Javascript or PHP anywhere near any of the stuff I work on daily. Lots of C, C++, some Go and Python.
Ah, OK, so it is more or less the latest version of ASaP/ASaP2. I just made a post up-thread about my memory of ASaP. It looked interesting, but as you point out, it has some real practical issues.
At the time we spoke with them, it sounded like whenever you loaded an algorithm chain, you had to map it to the specific chip you were going to run it on, even, to account for bad cores, different core speeds, etc. Each core has a local oscillator. Whee...
I'm familiar with Dr. Baas' older work (ASaP and ASaP2). He presented his work to a team of processor architects I was a part of several years ago.
At least at that time (which, as I said, was several years ago), one class of algorithms they were looking at was signal processing chains, where the processing steps could be described as a directed graph of processing steps. The ASaP compiler would then decompose the computational kernels so that the compute / storage / bandwidth requirements were roughly equal in each subdivision, and then allocate nodes in the resulting, reduced graphs to processors in the array.
(By roughly equal, I mean that each core would hit its bottleneck at roughly the same time as the others whenever possible, whether it be compute or bandwidth. For storage, you were limited to the tiny memory on each processor, unless you grabbed a neighbor and used it solely for its memory.)
The actual array had a straightforward Manhattan routing scheme, where each node could talk to its neighbors, or bypass a neighbor and reach two nodes away (IIRC), with a small latency penalty. Communication was scoreboarded, so each processor ran when it had data and room in its output buffer, and would locally stall if it couldn't input or output. The graph mapping scheme was pretty flexible, and it could account for heterogenous core mixes. For example, you could have a few cores with "more expensive" operations only needed by a few stages of the algorithm. Or, interestingly, avoid bad cores, routing around them.
It was a GALS design (Globally Asynchronous, Locally Synchronous), meaning that each of the cores were running slightly different frequencies. That alone makes the cores slightly heterogeneous. IIRC, the mapping algorithm could take that into account as well. In fact, as I recall, you pretty much needed to remap your algorithm to the specific chip you had in-hand to ensure best operation.
The examples we saw included stuff familiar to the business I was in—DSP—and included stuff like WiFi router stacks, various kinds of modem processing pipelines, and I believe some video processing pipelines. The processors themselves had very little memory, and in fact some algorithms would borrow a neighboring core just for its RAM, if it needed it for intermediate results or lookup tables. I think FFT was one example, where the sine tables ended up stored in the neighbor.
That mapping technology reminds me quite a lot of synthesis technologies for FPGAs, or maybe the mapping technologies they use to compile a large design for simulation on a box like Cadence's Palladium. The big difference is granularity. Instead of lookup-table (LUT) cells, and gate-level mapping, you're operating at the level of a simple loop kernel.
Lots of interesting workloads could run on such a device, particularly if they have heterogenous compute stages. Large matrix computations aren't as interesting. They need to touch a lot of data, and they're doing the same basic operations across all the elements. So, it doesn't serve the lower levels of the machine learning/machine vision stacks well. But the middle layer, which focuses on decision-guided computation, may benefit from large numbers of nimble cores that can dynamically load balance a little better across the whole net.
I haven't read the KiloCore paper yet, but I suspect it draws on the ASaP/ASaP2 legacy. The blurb certainly reminds me of that work.
And what's funny, is about 2 days before they announced KiloCore, I was just describing Dr. Baas' work to someone else. I shouldn't have been surprised he was working on something interesting.
Came here to say the same thing. The nice thing about a compact proof is that it may generalize to other situations or offer greater insights. This is certainly not a compact proof. But, to say it's not a proof is ludicrous. It's a very explicit and detailed proof.
It's the difference between adding up the numbers 1 through 100 sequentially (perhaps by counting on your fingers even), and using Gauss' insight to take a short cut. The computer didn't take any insight-yielding shortcuts, but still got the answer.
________
(And yes, Gauss' story is probably apocryphal; but still the difference between the approaches is what I'm getting at.)
(I say "insight-yielding shortcut" to distinguish it from the many heuristics that modern SAT solvers use, including the one used here.)
Dave's argument starts with real-world numbers regarding solar insolation and PV conversion efficiency to establish a baseline. The exact details of a specific implementation won't change the broad conclusion that the energy balance alone, even if you take out the gee-whiz features of the Solar Freakin' Roadways design such as LEDs and networking, doesn't make sense.
When you add all the other stuff on top, it only gets worse.
Fundamental issues: Only so much sun hits the earth, and PV cells only convert a certain fraction to usable energy. When you mount them flat on the ground, you reduce their efficiency further because they're not perpendicular to the incoming light. When you put them under thick enough glass to support real physical loads such as cars and trucks, you lose even more. And when you distribute them over a large area, transmission losses become a Big Deal.
I'm personally skeptical you could build solar panels that would withstand actual vehicle traffic, at least the way we build roads here in the US. Real world roads aren't flat, and they change shape over time as they wear and as the road bed settles and degrades. But real world glass isn't very plastic, and won't conform to a changing surface. It's more likely to crack and break into many pieces. Likewise for the PV cells under it. You'd have to put some beefy steel plates under these to guarantee a sufficiently flat mounting surface to support the load-bearing glass.
Seems like this should just affect Chrome / Chromium and anything derived from those, as it's an implementation issue in the V8 JavaScript interpreter. (V8 is the name for the engine in Chrome.)
That is, it's not a JavaScript / ECMAScript bug in the standard (as implied by the headline), but rather a bug in one company's implementation.
Compare/contrast with the comically bad PRNG enshrined in the C standard itself:
static unsigned long int next = 1;
int rand(void)// RAND_MAX assumed to be 32767
{
next = next * 1103515245 + 12345;
return (unsigned int)(next/65536) % 32768;
}
Thankfully, though, this is just an example, and not required by the standard. But, many simple C compilers use that implementation. It's got plenty of problems, such as always alternating between even and odd values. If the last value was odd, the next value is even....
Without seeing the linked site, it's hard to say what exactly the EXE was meant to accomplish. If it's some sleazoid V14GRA site, or Scan Your PC Now for Viruses site, it's pretty easy to call it malware.
Some relevant information was redacted, unfortunately.
So... does anyone actually put a set top box on top of their TV set these days? Once upon a time, TVs were deep enough front-to-back to support this; these days, most aren't.
Or is this a term that was once accurate, but will never be accurate again, like "dialing" a phone? It's been a long time since phones had dials, unless they're being purposefully retro.
The rationale given is: "The kernel now keeps timestamps relative to the system boot time.
Among other things this fixes bogus uptime readings if the system time
is altered."
Presumably, this means the internal timestamps Hurd uses are now all monotonically increasing, regardless of any changes to the system time. Obviously, there's a relationship between the internal timestamp and what POSIX calls time_t (and related such datatypes). As I read it, they've decoupled the notion of system time (ie. something that resembles what you'd read from a clock, representing time and date as humans understand it, and subject to humans or network time daemons messing with that setting) from the internal timestamps it uses for computing the relative passage of time, such as 'uptime', network timeouts, etc.
The kernel now allows non-privileged users to wire a small amount of memory.
This is not a typo. Wiring memory means pinning it in memory so it cannot be paged out. This is potentially important both for security and real-time applications. On the security front, memory containing keys and passwords should be wired to prevent it going to disk. On the real-time front, if you can fit your working set in wired memory, you can be guaranteed you won't suffer a paging fault while you stay within that working set.
In Linux / POSIX systems, this is what mlock accomplishes.
Being able to write to memory, in contrast, isn't particularly noteworthy. You've been able to do that since pretty much the beginning...
I'd expect it to be a very minor effect. I'm not aware of anyone getting worried about this.
Got it. With everything else you've explained, that makes sense.
A related effect is convergent evolution. Say two species of bacteria each colonize high temperature environment. Then certain mutations which are favoured in high temperature will likely occur in both of them. When we compare their DNA, this can make it look like they are more closely related than they really are.
Ah, that also makes sense.
I thank you again for the informative responses. You've expertly escorted me up to (or possibly even well past) the edge of my competency.:-) I've certainly enjoyed the trip.
It's truly a fascinating topic, but for me to really get much more out of it, I think I need to do some homework to learn more about what's already known. There's only so much a generically analytic mind can do w/out learning what's already known in the field.
Thank you for the thoughtful and detailed response. I think I have a better understanding. (But, I'll always stay mindful of the Dunning-Krueger effect...;-) )
BTW, this statement captures something I was trying to express more clearly than I stated it:
(Actually it tends to be the other way around - we see islands of conserved sequence, and deduce therefore that they have a function. This isn't how genes are detected, as there are more sensitive gene-specific ways of doing this.)
What I was trying to get at was that if a section of DNA performs some useful function, even if we don't know what it is, it'll tend to be preserved because selection pressure will tend to preserve it by "selecting out" individuals whose mutations tampered with it. The observed long-term mutation rate for any given point should in some sense be inversely related to that point's significance. (More significant => fewer mutations, likely by a function much more stark than just "1/x", where "x" is significance. Key proteins should have a really strong bias to remain unmodified in viable offspring, for example.)
I now have a slightly different question: You mentioned the rate of repeated mutations, where the same piece of DNA was mutated twice or more, sometimes back to its original state. Suppose the environment shifts, such that selection pressure would favor a certain set of mutations to adapt a species to that new environment, and then the environment shifts back. I'm thinking fairly long term, cyclic shifts such as ice ages and the like.
Would such cyclic shifts meaningfully affect the assumptions underlying the multiple mutation rate? You gave this example: "if you compare two sequences and they differ in 10% of sites, it is reasonable to think that 1% of sites have actually mutated twice." I realize you mentioned it was oversimplified. It jibes with a basic knowledge of statistics and statistically independent random variables. I guess what I'm getting at is that cyclic shifts that affect which mutations improve, decrease or are neutral with respect to fitness would imply at least some of the variables aren't independent.
I guess it comes down to what fraction of the mutations actually affect fitness with respect to these cyclic forces. I imagine it's a fairly small proportion relative to the total set of mutations whose fitness effects are completely orthogonal to those long-term cyclic changes. If that's the case, am I correct thinking the effect wouldn't be large?
I guess in general, if the total delta between two samples is still relatively small (10% in your example), any second order effect such as this could only affect that approx 1%, and so that already bounds the potential error from simplifying assumptions anyway.
Again, thank you for your helpful (to my understanding, at least) response.
Let me see if I understand. By measuring over a long period, we're measuring the long term rate of mutation survival after applying selection pressure, and that could be noticeably different than the raw rate of mutation. Is that a correct summary?
Please go slowly with me. I'm an engineer, not a biologist, and I admit biology is not my strongest subject. I am actually curious, though.
I remember hearing that there are large sections of DNA in many living things that are effectively "junk DNA," or at least we think are junk DNA. By junk DNA, I mean DNA that doesn't code for any useful proteins or other molecules, and generally seems to take up space. (I'm skeptical that there is much that is really "junk," but bear with me.) If there really are large stretches of non-useful baggage, it would stand to reason that these sections would not be subject to selection pressure, and so mutations to these sections aren't directly subject to selection pressure, because they don't affect the fitness of the organism.
Is there a way to measure the mutation rates for different sites in the overall genome of a given organism, so that: (a) we can determine if some regions are actually junk because mutations to them do not affect organism fitness, and (b) can distinguish between the rate of mutation and the rate of mutation survival? (This question more or less assumes my understanding in the first paragraph is accurate.)
Yep. The actual secret ingredient (at least for a Flint-style coney, which is my fave) is finely ground beef heart.
BTW, nobody I know in Michigan calls the sauce "chili." If you want a chili dog, by all means have one 'cause they're tasty too, but don't confuse it with a coney dog.
Outside Michigan? Everything that claims to be a Coney dog is just a dang chili dog.
I don't know who modded me down for trying to be funny. Coney dogs are a staple in that neck of the woods. I love 'em. I grew up not too far from there.
Anyone can put up a web page, and Javascript and PHP have a large footprint there. (I guess Java, on the enterprise server side?) It's not hard to imagine there's lots of folks that have to deal with these languages as part of their larger duties, but aren't really trained as programmers in any traditional sense. That could fuel a bunch of StackOverflow traffic for sure...
Whichever ranking you look at will be skewed by the methodology. It feels like web-oriented languages are overemphasized in this cut.
Of course, my own worldview is skewed, too. I deal more with low-level hardware, OS interactions, etc. You won't find a lick of Javascript or PHP anywhere near any of the stuff I work on daily. Lots of C, C++, some Go and Python.
Ah, OK, so it is more or less the latest version of ASaP/ASaP2. I just made a post up-thread about my memory of ASaP. It looked interesting, but as you point out, it has some real practical issues.
At the time we spoke with them, it sounded like whenever you loaded an algorithm chain, you had to map it to the specific chip you were going to run it on, even, to account for bad cores, different core speeds, etc. Each core has a local oscillator. Whee...
I'm familiar with Dr. Baas' older work (ASaP and ASaP2). He presented his work to a team of processor architects I was a part of several years ago.
At least at that time (which, as I said, was several years ago), one class of algorithms they were looking at was signal processing chains, where the processing steps could be described as a directed graph of processing steps. The ASaP compiler would then decompose the computational kernels so that the compute / storage / bandwidth requirements were roughly equal in each subdivision, and then allocate nodes in the resulting, reduced graphs to processors in the array.
(By roughly equal, I mean that each core would hit its bottleneck at roughly the same time as the others whenever possible, whether it be compute or bandwidth. For storage, you were limited to the tiny memory on each processor, unless you grabbed a neighbor and used it solely for its memory.)
The actual array had a straightforward Manhattan routing scheme, where each node could talk to its neighbors, or bypass a neighbor and reach two nodes away (IIRC), with a small latency penalty. Communication was scoreboarded, so each processor ran when it had data and room in its output buffer, and would locally stall if it couldn't input or output. The graph mapping scheme was pretty flexible, and it could account for heterogenous core mixes. For example, you could have a few cores with "more expensive" operations only needed by a few stages of the algorithm. Or, interestingly, avoid bad cores, routing around them.
It was a GALS design (Globally Asynchronous, Locally Synchronous), meaning that each of the cores were running slightly different frequencies. That alone makes the cores slightly heterogeneous. IIRC, the mapping algorithm could take that into account as well. In fact, as I recall, you pretty much needed to remap your algorithm to the specific chip you had in-hand to ensure best operation.
The examples we saw included stuff familiar to the business I was in—DSP—and included stuff like WiFi router stacks, various kinds of modem processing pipelines, and I believe some video processing pipelines. The processors themselves had very little memory, and in fact some algorithms would borrow a neighboring core just for its RAM, if it needed it for intermediate results or lookup tables. I think FFT was one example, where the sine tables ended up stored in the neighbor.
That mapping technology reminds me quite a lot of synthesis technologies for FPGAs, or maybe the mapping technologies they use to compile a large design for simulation on a box like Cadence's Palladium. The big difference is granularity. Instead of lookup-table (LUT) cells, and gate-level mapping, you're operating at the level of a simple loop kernel.
Lots of interesting workloads could run on such a device, particularly if they have heterogenous compute stages. Large matrix computations aren't as interesting. They need to touch a lot of data, and they're doing the same basic operations across all the elements. So, it doesn't serve the lower levels of the machine learning/machine vision stacks well. But the middle layer, which focuses on decision-guided computation, may benefit from large numbers of nimble cores that can dynamically load balance a little better across the whole net.
I haven't read the KiloCore paper yet, but I suspect it draws on the ASaP/ASaP2 legacy. The blurb certainly reminds me of that work.
And what's funny, is about 2 days before they announced KiloCore, I was just describing Dr. Baas' work to someone else. I shouldn't have been surprised he was working on something interesting.
Came here to say the same thing. The nice thing about a compact proof is that it may generalize to other situations or offer greater insights. This is certainly not a compact proof. But, to say it's not a proof is ludicrous. It's a very explicit and detailed proof.
It's the difference between adding up the numbers 1 through 100 sequentially (perhaps by counting on your fingers even), and using Gauss' insight to take a short cut. The computer didn't take any insight-yielding shortcuts, but still got the answer.
________
(And yes, Gauss' story is probably apocryphal; but still the difference between the approaches is what I'm getting at.)
(I say "insight-yielding shortcut" to distinguish it from the many heuristics that modern SAT solvers use, including the one used here.)
Dave's argument starts with real-world numbers regarding solar insolation and PV conversion efficiency to establish a baseline. The exact details of a specific implementation won't change the broad conclusion that the energy balance alone, even if you take out the gee-whiz features of the Solar Freakin' Roadways design such as LEDs and networking, doesn't make sense.
When you add all the other stuff on top, it only gets worse.
Fundamental issues: Only so much sun hits the earth, and PV cells only convert a certain fraction to usable energy. When you mount them flat on the ground, you reduce their efficiency further because they're not perpendicular to the incoming light. When you put them under thick enough glass to support real physical loads such as cars and trucks, you lose even more. And when you distribute them over a large area, transmission losses become a Big Deal.
I'm personally skeptical you could build solar panels that would withstand actual vehicle traffic, at least the way we build roads here in the US. Real world roads aren't flat, and they change shape over time as they wear and as the road bed settles and degrades. But real world glass isn't very plastic, and won't conform to a changing surface. It's more likely to crack and break into many pieces. Likewise for the PV cells under it. You'd have to put some beefy steel plates under these to guarantee a sufficiently flat mounting surface to support the load-bearing glass.
Seems like this should just affect Chrome / Chromium and anything derived from those, as it's an implementation issue in the V8 JavaScript interpreter. (V8 is the name for the engine in Chrome.)
That is, it's not a JavaScript / ECMAScript bug in the standard (as implied by the headline), but rather a bug in one company's implementation.
Compare/contrast with the comically bad PRNG enshrined in the C standard itself:
static unsigned long int next = 1; // RAND_MAX assumed to be 32767
int rand(void)
{
next = next * 1103515245 + 12345;
return (unsigned int)(next/65536) % 32768;
}
Thankfully, though, this is just an example, and not required by the standard. But, many simple C compilers use that implementation. It's got plenty of problems, such as always alternating between even and odd values. If the last value was odd, the next value is even....
Without seeing the linked site, it's hard to say what exactly the EXE was meant to accomplish. If it's some sleazoid V14GRA site, or Scan Your PC Now for Viruses site, it's pretty easy to call it malware.
Some relevant information was redacted, unfortunately.
QNaN or SNaN? I guess it depends if you need more braaaaaaaaains.
Awesome. Thanks!
I'd love to believe you, especially since I enjoy a good curry. Got a link?
Maybe they like the clingy feel of the static on the CRT. Or maybe, it's just cats being cats. I know mine like getting between me and the monitor.
Niiiiice. Something tells me, though, your setup is unique. :D
I admit to being a bit of a smartass. :-) Our language is rife with these fossils.
Does this box sit on top of your TV? Or does it sit below it, next to it, etc.?
So... does anyone actually put a set top box on top of their TV set these days? Once upon a time, TVs were deep enough front-to-back to support this; these days, most aren't.
Or is this a term that was once accurate, but will never be accurate again, like "dialing" a phone? It's been a long time since phones had dials, unless they're being purposefully retro.
He reused the MINIX filesystem layout, and initially hosted builds on MINIX, but to my knowledge he never directly incorporated code from MINIX. Some have claimed that, but no claim has ever stuck, especially given that Andrew Tanenbaum himself agrees that Linux didn't annex any MINIX code directly.
It appears Wikipedia's account jibes with my memory.
I can't tell if you're trying to be humorous.
The rationale given is: "The kernel now keeps timestamps relative to the system boot time. Among other things this fixes bogus uptime readings if the system time is altered."
Presumably, this means the internal timestamps Hurd uses are now all monotonically increasing, regardless of any changes to the system time. Obviously, there's a relationship between the internal timestamp and what POSIX calls time_t (and related such datatypes). As I read it, they've decoupled the notion of system time (ie. something that resembles what you'd read from a clock, representing time and date as humans understand it, and subject to humans or network time daemons messing with that setting) from the internal timestamps it uses for computing the relative passage of time, such as 'uptime', network timeouts, etc.
According to the release:
This is not a typo. Wiring memory means pinning it in memory so it cannot be paged out. This is potentially important both for security and real-time applications. On the security front, memory containing keys and passwords should be wired to prevent it going to disk. On the real-time front, if you can fit your working set in wired memory, you can be guaranteed you won't suffer a paging fault while you stay within that working set.
In Linux / POSIX systems, this is what mlock accomplishes.
Being able to write to memory, in contrast, isn't particularly noteworthy. You've been able to do that since pretty much the beginning...
Got it. With everything else you've explained, that makes sense.
Ah, that also makes sense.
I thank you again for the informative responses. You've expertly escorted me up to (or possibly even well past) the edge of my competency. :-) I've certainly enjoyed the trip.
It's truly a fascinating topic, but for me to really get much more out of it, I think I need to do some homework to learn more about what's already known. There's only so much a generically analytic mind can do w/out learning what's already known in the field.
Thanks again.
Thank you for the thoughtful and detailed response. I think I have a better understanding. (But, I'll always stay mindful of the Dunning-Krueger effect... ;-) )
BTW, this statement captures something I was trying to express more clearly than I stated it:
What I was trying to get at was that if a section of DNA performs some useful function, even if we don't know what it is, it'll tend to be preserved because selection pressure will tend to preserve it by "selecting out" individuals whose mutations tampered with it. The observed long-term mutation rate for any given point should in some sense be inversely related to that point's significance. (More significant => fewer mutations, likely by a function much more stark than just "1/x", where "x" is significance. Key proteins should have a really strong bias to remain unmodified in viable offspring, for example.)
I now have a slightly different question: You mentioned the rate of repeated mutations, where the same piece of DNA was mutated twice or more, sometimes back to its original state. Suppose the environment shifts, such that selection pressure would favor a certain set of mutations to adapt a species to that new environment, and then the environment shifts back. I'm thinking fairly long term, cyclic shifts such as ice ages and the like.
Would such cyclic shifts meaningfully affect the assumptions underlying the multiple mutation rate? You gave this example: "if you compare two sequences and they differ in 10% of sites, it is reasonable to think that 1% of sites have actually mutated twice." I realize you mentioned it was oversimplified. It jibes with a basic knowledge of statistics and statistically independent random variables. I guess what I'm getting at is that cyclic shifts that affect which mutations improve, decrease or are neutral with respect to fitness would imply at least some of the variables aren't independent.
I guess it comes down to what fraction of the mutations actually affect fitness with respect to these cyclic forces. I imagine it's a fairly small proportion relative to the total set of mutations whose fitness effects are completely orthogonal to those long-term cyclic changes. If that's the case, am I correct thinking the effect wouldn't be large?
I guess in general, if the total delta between two samples is still relatively small (10% in your example), any second order effect such as this could only affect that approx 1%, and so that already bounds the potential error from simplifying assumptions anyway.
Again, thank you for your helpful (to my understanding, at least) response.
Let me see if I understand. By measuring over a long period, we're measuring the long term rate of mutation survival after applying selection pressure, and that could be noticeably different than the raw rate of mutation. Is that a correct summary?
Please go slowly with me. I'm an engineer, not a biologist, and I admit biology is not my strongest subject. I am actually curious, though.
I remember hearing that there are large sections of DNA in many living things that are effectively "junk DNA," or at least we think are junk DNA. By junk DNA, I mean DNA that doesn't code for any useful proteins or other molecules, and generally seems to take up space. (I'm skeptical that there is much that is really "junk," but bear with me.) If there really are large stretches of non-useful baggage, it would stand to reason that these sections would not be subject to selection pressure, and so mutations to these sections aren't directly subject to selection pressure, because they don't affect the fitness of the organism.
Is there a way to measure the mutation rates for different sites in the overall genome of a given organism, so that: (a) we can determine if some regions are actually junk because mutations to them do not affect organism fitness, and (b) can distinguish between the rate of mutation and the rate of mutation survival? (This question more or less assumes my understanding in the first paragraph is accurate.)
Yep. The actual secret ingredient (at least for a Flint-style coney, which is my fave) is finely ground beef heart.
BTW, nobody I know in Michigan calls the sauce "chili." If you want a chili dog, by all means have one 'cause they're tasty too, but don't confuse it with a coney dog.
Outside Michigan? Everything that claims to be a Coney dog is just a dang chili dog.
I don't know who modded me down for trying to be funny. Coney dogs are a staple in that neck of the woods. I love 'em. I grew up not too far from there.
Could this be the secret ingredient in Coney sauce?
Which road was that again?