CppCast - C# and IL2CPP
Episode Date: September 21, 2017Rob and Jason are joined by Josh Peterson to talk about C# and some of the similarities and differences between the Managed language and C++, he also talks about his work at Unity 3D on IL2CPP. ... Josh is a programmer working at Unity Technologies, where he focuses on integration and development of scripting runtimes for the Unity 3D game engine. He enjoys learning about CPU architectures and assembly language, including the recent development of an MOS 6510 emulator in C#. In his free time, he coaches a number of youth soccer teams and reads philosophy and theology. News Energy Efficiency Across Programming Languages C++ World Café Useful GCC warning options not enabled by -Wall -Wextra Josh Peterson @petersonjm1 Links Microsoft C# Guide Unity 3D An introduction to IL2CPP internals Sponsors Backtrace JetBrains Hosts @robwirving @lefticus
Transcript
Discussion (0)
This episode of CppCast is sponsored by Backtrace, the turnkey debugging platform that helps you spend less time debugging and more time building.
Get to the root cause quickly with detailed information at your fingertips.
Start your free trial at backtrace.io.cppcast.
And by JetBrains, maker of intelligent development tools to simplify your challenging tasks and automate the routine ones.
JetBrains is offering a 25% discount for an
individual license on the C++ tool of your choice, CLion, ReSharper, C++, or AppCode.
Use the coupon code JetBrains for CppCast during checkout at JetBrains.com.
Episode 119 of CppCast with guest Josh Peterson recorded September 20th, 2017.
In this episode, we talk about C++ user groups around the world and GCC warnings.
Then we talk to Josh Peterson from Unity3D.
Josh talks to us about C++ developers by C++ developers.
I'm your host, Rob Irving, joined by my co-host, Jason Turner.
Jason, how are you doing today?
I'm doing pretty good, Rob. How are you doing?
Doing good. You have a little chaos going on in your house right now, though, right?
Yes, my house is currently being inspected by a team of 25 home inspection students.
We volunteered it for that.
But on a side not related to my house being inspected at the moment,
is I have been like, I really wanted to hit the goal of getting 10 000 subscribers for c++ weekly before cbp con this year at this exact
moment i'm at 9999 so hopefully i will actually get past 10 000 subscribers so by the time this
episode airs hopefully you've hit that but if not and you're listening and you haven't subscribed
c++ weekly go uh go check out the youtube channel i think that sounds like a great
plan well i get like 15 subscribers a day on average new subscribers a day so i really expect
like i you know by the end of the episode to be at 10 000 but it's an exciting moment for me so i
thought i'd share it yeah 10 000 is a lot lot. You got there pretty quickly, it seems.
Well, it might feel that way to you.
How many episodes are you on now?
83 episodes.
83 weeks I've been doing it straight.
Wow.
Okay.
Well, at the top of your episode, I'd like to read a piece of feedback.
This week we got an email from Harold, who is one of the organizers for the Sweden C++ user group.
And he wrote in to tell us about this joint user group meeting, a distributed user group meeting between the Sweden C++ group and the London C++ group, which is pretty interesting.
Yeah. I guess in London and in Sweden,
Stockholm, where the two groups meet,
the company King
has a headquarters in both locations
or building in both locations.
So they're holding the meetup
and they're going to basically take turns
presenting content.
So London will present some, Sweden will present some,
and the other group will be watching it online,
which is pretty cool.
Yeah, and since I guess there's an hour time difference between the two of them,
they're doing like one of them's doing lunch at the front or dinner at the front end,
one's doing the dinner at the back end or something like that.
That looks like a neat setup.
Yeah, I'm not sure if they're broadcasting any of the content to people outside of the user group
or if it's meant just to be for the people in the user group.
But if you're in London or Sweden,
and you're not regularly going to this user group already,
it's probably worth checking out.
Yeah, and that's October 26th, it looks like.
Yes.
Well, we'd love to hear your thoughts about the show as well.
You can always reach out to us on Facebook, Twitter,
or email us at feedback at cpcast.com.
And don't forget to leave us a review on iTunes.
Joining us today is Josh Peterson.
Josh is a programmer working
at Unity Technologies, where he focuses on
integration and development of scripting
runtimes for the Unity 3D
game engine. He enjoys learning about
CPU architecture as an assembly language,
including the recent development of an
MOS6510 emulator
in C Sharpsharp.
In his free time, he coaches a number of youth soccer teams and reads philosophy and theology.
Josh, welcome to the show.
Hey, thanks for having me. I'm glad to be here.
Interesting that you specifically call out the 6510 version.
Yes, I'm probably not as versed in all the versions as you are,
but I guess 6510 was maybe a little more memory than 6502, right?
Is there another difference? I'm not sure.
As far as I know, the only difference is that the 6510 has an I.O. port on it.
Okay.
Yeah, there's plenty of people who know the mods, those processors,
much better than I do,
but I thought it would be a fun one to try to write an emulator for. I know there's at least three people listening to this podcast when it airs who would correct us on everything that we just said.
Please do, because I'd like to know more.
Do you have a specific goal for a system that you want to emulate, or just the CPU?
I do.
I'd like to put together something for playing with assembly language or learning assembly language.
I thought the assembly language
for the MOS 65
100 series is pretty simple.
It's a CPU that I could write an emulator for.
I know
there's already some out there, too. I think there's
at least one website that does it in JavaScript
and you can actually type in the assembly code and
see it execute. I had something
like that in mind, but we'll see.
Yeah, I actually used that JavaScript 6502 website
when I was preparing for my CppCon talk last year.
It was handy.
Yeah, it's really nice.
But it was fun writing the emulator.
I learned a lot about 6502 and CPUs in general.
Yeah, my cousin,
one of his hobbies is every time he picks up a new language or a new system
is to port his Nintendo emulator to it.
So he has done one, I believe, in C Sharp and in TypeScript
and Rust and C at this point.
Wow.
And the 8-bit Nintendo?
Yeah.
So that would be a 6502, right?
Yeah, which is why I brought it up.
So yeah, maybe I don't fully understand the 6510 to 6502 distinction,
but hopefully someone will help me out.
Yeah, yeah.
There's no reason to get into the weeds there.
I can think of this.
Anyhow, I'm not sure.
I would have to look to double-check.
Okay, Josh. Wellosh well we got a couple
news articles to discuss uh feel free to comment on any of these and then we'll start talking to
you more about uh the work you're doing at uni and c-sharp and il2cpp okay okay okay uh so this
first article uh is this paper about energy efficiency across programming languages.
How does energy, time, and memory relate?
And I don't know about you guys, but I didn't read the whole paper,
but I did browse through the set of results a little bit and was happy to see that C++ is always at the top of the chart.
Not the very top.
Usually C, C++, and Rust are kind of grouped in the top three positions between the different tests that they ran through.
Yeah, I find this slightly confusing, personally.
Because I know, I read somewhere else that they based all this on the language shootout comparisons.
So, I mean, there's already a suite of these tests for all these different languages, right?
So they were able to run them.
They didn't have to write their own suite of tests. So I expected
to see a direct correlation between
wall clock time
and
power usage, but that's not what you see.
So like
looking at the binary tree comparison,
C++ is actually one of the slower
ones, but again, they're using someone else's
thing. It's 63 seconds,
even though it took it was only
the second and the amount of cpu usage or excuse me and uh power usage yeah i don't quite understand
the difference there yeah that seems to be what we find a lot with especially on mobile platforms
so you know the code that actually executes faster is better for energy, right? Because there's fewer instructions.
Right.
I do recall, it's probably maybe five years ago,
I think Herb Sutter gave a talk about kind of the future of C++.
I don't know if you guys remember this.
I think it was right after C++11,
but about how languages would be judged based on something like performance per watt.
I think it's what he said.
And I don't know.
It seems like this sort of analysis indicates that's becoming more and more the case
with mobiles and data centers and whatnot.
Languages which are energy efficient can be really beneficial.
So we don't want to be running all of our high-performance computations
with Ruby or Perl, it looks like.
If I were to take a quick glance at all of the bottom of the rankings
across these tests.
Yeah.
Python's really pretty low down there, too.
Yeah.
Interpreted languages without any sort of compile time optimization or anything.
You know?
Yep. Okay. languages without any sort of compile time optimization or anything.
Okay, next one.
Jason, you were actually a part of this, the C++ World Cafe.
I was.
We were just talking about that distributed user group.
This seems like kind of a similar thing, a user group happening online.
Am I right?
Well, no, it's kind of the inverse in a way, I guess.
They had their user group that was meeting in Germany,
and they had the four of us call in to people running Skype on their laptops.
So we were just four, specifically four individuals joining in with this one user group.
And I didn't interact with any of the other people who called in.
I was just interacting with the table that I was at.
It was interesting.
But it was a lot of fun, actually, from my perspective,
because apparently I was just available to keep chatting.
So I just stayed on the line with them for, I don't know, over an hour or something,
and just got the chance to just chat with some of our C++ users in Germany and talk to them about their experiences learning C++ and
stuff. I had a great time doing it. Cool. And your topic was how can I become a better C++
developer? It looks like, and I saw there, there's a transcript of the conversation that all you and
the other three guests were having. Is it not recorded,
though? Is it just the transcript? I thought, oops, I thought that there was going to be a
video posted also. But it's been actually a while ago that we did this. It took him,
you know, understandably, yeah, June 14, took him a while to go through and like organize everything
and type out all the transcripts
and double check it for errors and whatever but i agree i don't see a link to the video so that
must not have gone up okay well i really like the idea of these kind of online user groups
and distributed user groups uh you know just more ways to bring the community together yeah
yeah okay and then the last one we have today is useful gcc warning options not
enabled by w all and w extra and i thought a couple of these warnings were uh seem to be
pretty useful it definitely seems like uh you know maybe they should be included in w all w extra i
don't know who makes that decision i just i, I find it ridiculous that there's this flag called all, which is not all.
And then there's a flag called extra, which is more than all, but still not all.
But, you know, it's historical.
They don't want to risk enabling too many warning options that are going to break people's builds who compile with w air but um
i'm not that nice i guess if i were a compiler developer i'd turn them all on
well i wonder is there is there a a way or a possibility of moving kind of warnings into
the standard you know so you could say these are the standard set of warnings that all compilers should implement and maybe they have a standard wording or a number system yeah there was who did
we talk to about that patrice briefly or something possibly the possibility of something like that
maybe someday happening but i think it would take so much effort to get everyone to agree
but i think we have we have two things right now that i think virtually everyone agrees on I think it would take so much effort to get everyone to agree.
But I think we have two things right now that I think virtually everyone agrees on,
that falling through switch conditions
is maybe not something you want to do,
and unused variables is something that maybe you don't want to do.
And so then we have the attributes in C++17
for those two things where we can selectively disable them when we want to.
But
creating a consensus on what everyone agrees should be
a warning, I'm guessing, would be...
Well, maybe you should volunteer,
Josh, to spearhead that.
I guess it's not surprising that you say that. That makes sense,
right? If it's your idea, then...
That wasn't my idea.
You said there should be a standard set of warnings.
Oh, okay.
No, I'm sure other people have had the same idea.
Maybe someone else will.
Maybe I will.
But I guess if there was at least maybe a framework in the standard for, like you said,
maybe those two go in first, and that's easy because everyone agrees,
and then you can incrementally pull in other ones.
I know we can get into this later,
but we have a tool that generates C++ code,
and we work hard to have that be warning-free,
which is really difficult across multiple compilers.
So we have to figure out,
are we going to ignore certain warnings
or are we going to pragma them out?
Well, you know, I mean,
maybe we can talk about that briefly now
since you just brought it up.
Why do you do that?
Do you, if you work with GCC and Clang,
do you, what warning levels do you guys use?
So for the code that we generate,
okay, so maybe we'll back up real quick.
So one of the main tools I work on at Unity
is called IL2CPP.
And that's something we'll definitely dig into in a minute, right?
Yes.
Okay.
But the idea is it converts.NET bytecode to C++ code.
Okay.
And then we try to do as best as we can have that C++ code compile without warning.
So in our internal tests, we turn on W error on GCC and Clang.
And I don't remember what the flag is on Microsoft compilers, but the same flag.
And then we go through and we disable maybe a half dozen warnings that we know that we have problems with.
And we kind of try to pick those off, you know, over time.
Because of the nature of some differences between the.NET runtime and the way IL works and the way C++ works, there are some kind of impedance mismatches that prevent us from turning off all the warnings.
Okay.
But, um, but the idea is basically in our test code we do that.
And then, uh, in our, for our users, they run the same tool and then they'll compile it on their machine with a platform-specific compiler.
Um, in that case, we don't apply WArror. We want it to compile even if there are still warnings on their machine with a platform-specific compiler. In that case, we don't apply WArror.
We want it to compile even if there are still warnings on their machines.
And that's to catch cases where we may be missing something in our test suite,
like it's a bit of IL code that we don't have covered in our test suite yet.
And so we'll generate a warning that we aren't expecting or something.
Okay.
We'll definitely have to dig into all of this a lot more in a minute.
Yeah. We'll definitely have to dig into all of this a lot more in a minute. Yeah, so let's back up a little bit and start out by telling us a little bit about your job at Unity3D
and kind of why you live in both the C Sharp and C++ world.
Sure, so Unity Technologies is a company I work for which makes the Unity3D game engine.
I think it's relatively well known by now.
I think we've been around for 10 or 15 years.
I'm not sure exactly how long.
But in any case, the Unity 3D, the game engine,
is mostly written in C++.
The scripting language exposed to users is C Sharp
and a few other languages we can talk about,
but mainly C Sharp.
And so things are built on top of a.NET runtime.
In the.NET world,
there's a couple of different runtimes. There's Microsoft's, they actually have a few. And there's a pretty cool one called Mono, which is an open source project to implement a.NET runtime,
a C-sharp compiler, all these different tools that you need for a whole.NET environment and
ecosystem. And that's been around almost since.NET has from Microsoft. So Unity is a native application written in C++
that hosts the mono runtime internally. And so then users can write C-sharp code. We run the
C-sharp compiler on that code, and then we execute that code with the Mono runtime inside the Unity application.
And so the role of my team is to, we maintain the integration with Mono, and we also work on new development in that area.
So that involves things like integrating the C Sharp compiler into our tool chain and into our user's tool chain,
making sure the runtime works across all of the platforms Unity supports,
which is a pretty large number.
I think it's something like 20 or 30 now.
Basically any platform you can play a game on,
you can write a game in Unity for.
So we maintain that across those platforms.
And then the other thing we've done is this thing we call IL2CPP,
which, like I said earlier, translates IL bytecode. So's kind of the the stuff that dot a dot net runtime executes
it translates that into c++ and then we compile that with a platform specific compiler
and then we have an implementation of the dot net runtime so the same thing that that mono does from
the runtime side of things we We implemented that in C++,
and then we can execute our generated C++ code,
and it uses our C++.NET runtime to make everything work.
So my team developed the IELTS CPP technology,
and we maintain it,
and we maintain the Mono integration with Unity.
So maybe we should start off by talking a little bit about IL and kind of the differences
in what a C Sharp compiler produces and what a C++ compiler produces.
Yeah, I think that makes sense.
So when you compile C Sharp code, you get this thing called IL, which I guess I should
have mentioned that's called intermediate language.
So it's a bytecode format.
A lot of languages have a similar bytecode format.
I think Java does and maybe some interpretive languages have a similar bytecode format. I think Java does, and maybe some
interpretive languages. I'm not entirely sure. But IL is kind of like assembly. You can think
of it like that. So it executes on top of a virtual machine. And the virtual machine is
often called the.NET virtual machine. It's kind of like a real CPU, but without registers. So a
lot of virtual machines operate like this.
They're stack-based, so they have the concept of memory in the sense of a stack.
So I can push and pop things onto a stack, and then I can call functions.
I can do really simple flow control with go-tos.
I can define types, structs, and classes, these kind of things.
All that stuff works in IL.
So C Sharp Compiler emits this IL,
and then anybody who can execute that IL,
anybody who implements a.NET virtual machine
can run the IL.
And there's kind of four big virtual machine implementations
out there right now.
So Microsoft has the.NET framework,
which is kind of the classic one that's been around for a while.
They've recently built a new one called.NET Core.
And that's fully open source and portable across, I think, Windows, Linux, and Mac, and maybe a few other platforms now.
And then Mono, which is the one that Unity uses.
And then IELTS and CPP, the one we developed internally.
There might be others, but those are kind of the four biggest ones
as far as production use that I'm aware of.
So C++, of course, is different
because C++ compilers are emitting machine code
directly for whatever operating system and architecture
that you're compiling for.
So I can imagine if you're a C Sharp developer,
I can compile this code
down to what's called an assembly
which would be like a DLL or an executable in.NET
and that's just an IL bytecode
and I can take that assembly to any
platform that supports.NET
I can take the same assembly
to Mac, Linux, Windows
any place that can execute.NET
and execute it
and it theoretically should execute the same way if the.NET virtual machine is working properly.
And of course, with C++, that's not possible.
One of the other cool things about IL from a developer perspective is it can be disassembled pretty easily.
So there's a couple of utilities out there.
One's called IL Spy, which is an open source project.
And JetBrains has one called DotPeak. And
both these two utilities can take an IL assembly that was generated from a C Sharp compiler,
or really from any compiler that supports IL, and you can fully inspect it. You can
see all the IL code with pretty high fidelity. So it's interesting if you're a C Sharp developer
and you're thinking about, you know, I want to get involved in C++, right?
A big thing about C++ is being really close to the machine.
You can often reason about,
how is my C++ code going to look like in the target machine language?
And you can use Compiler Explorer or tools like that to really actually see that.
It's a little more difficult to do that with C Sharp because you've got that.NET runtime, which is doing the actual conversion to machine code see that. It's a little more difficult to do that with C Sharp
because you've got that.NET runtime,
which is doing the actual conversion to machine code for you.
But it is really easy in C Sharp to see the IL code.
And if you can take your C Sharp assembly that you compiled,
use one of these tools to disassemble it and look at the IL,
I think that's really beneficial
because you can see what constructs in C Sharp create a lot of IL,
which ones create a small amount of IL.
And really, if you can understand IL,
you can understand most assembly languages.
They're really similar.
So I spent a little bit of time last year
looking at the Java bytecode generated by the Java compiler.
And I was kind of surprised to notice
that it did, like, no optimization at all.
And it seems to be that their argument is well the
uh you know the jit will take care of that i'm curious how much of a is it like a one-to-one
correlation from your c-sharp to your il or does it do optimization like we would expect the c++
compiler to do i think most c-sharp compilers are not doing a whole lot of optimization okay um
they're getting better so mic Microsoft's compiler, Roslyn,
is kind of their new compiler framework,
which is open source.
And it does more optimization
than their previous C Sharp compilers did.
But a lot of the work is still done by the runtime.
So Microsoft has a new JIT run.
Okay, maybe I should back up.
So an acronym JIT is useful here.
It's a just-in-time compiler.
That's how most.NET, and I think, I'm not sure about Java,
but I think Java's the same, but most.NET stuff works via JIT, right?
The IL code is JITed, so it's compiled on the user's machine to machine code kind of as it's executed,
and then that compiled binary is saved for the
next time the same function gets called or something and you reuse it. It doesn't rejit.
So Microsoft has a pretty new JIT compiler for IAL called RyuJIT, and it does a lot of
optimization. So the kind of things you'd expect in a C++ compiler to do, the kind of things you
see in Clang or GCC from different types of optimization passes,
the JIT compiler does that.
So I think in the end, the goal of the C Sharp compiler
is to produce IL, you know, that the JIT compiler can work with,
but it's not doing a significant amount of optimization.
Interesting. Okay.
Okay.
John, talk a little bit about some of the main differences that people think of between a managed language and C++. I say new list of int or something like that, right?
That's going to tell the C Sharp compiler,
hey, I want to create a new object,
and I want the garbage collector to manage that memory.
So there's no need in C Sharp to deallocate or call free or delete
or any of the things we see in C++
because the garbage collector will track all the references to that memory
and it'll remove the memory whenever it sees fit
when nobody's referring to it anymore.
There's similar concepts between C Sharp and C++
in the sense of the heap and the stack.
So both languages have that capability
to either allocate things on the stack,
just a small scope or a function scope,
or allocate things on a heap.
The difference with C++, of course, is when you say new, right,
you get a heap allocation.
It's up to the programmer to specifically free
and deallocate that memory.
As a C Sharp developer, you know,
you don't think too much about that in a lot of cases, right,
because the GC handles it.
But at least from the
perspective of the code we see in Unity, that can matter because the GC is non-deterministic.
So if I'm doing a game or maybe even a server application where I need to have some sort of a
response time guarantee, the GC can really be a problem. Now the better the the better the gc implementation is the less of a
chance that'll be a you know be an issue but you can still get a non-deterministic you know time
where your application is stopped because the gc has to go do something so there are ways in c-sharp
to avoid garbage collection there's kind of two different categories of types, I guess is the best word in C Sharp.
You have reference types and value types.
So in C Sharp, something like an int or a double is a value type.
It's never allocated on the GC heap.
It's always allocated on the stack.
And then a class, a user-defined class,
is a reference type, which is always allocated on the GC heap.
And you have this kind of in-between type called a struct in C Sharp, which is a little different
from C++. So creating a struct in C Sharp is a user-defined type, but by default, it's going to
be allocated on the stack. And that gives you really tight control of the memory then. If you
want to write C Sharp code with structs and value types, you can use kind of
scope based memory management in a sense, because you're not going to the garbage collector.
But if you're coming to coming to C plus plus from C sharp,
you know, you need to consider the fact that you have to do something to free that memory,
right? And of course, in modern C, C plus plus, that's not calling new and delete,
right? We want to pretty much avoid those.
If you're using, what, C++11, maybe C++14 or later,
unique pointer and shared pointer and all the tools you need are there in C++.
So I think it's certainly possible in modern C++ to avoid any manual memory management in most cases.
So I'm thinking about from a programmer,
what I'm thinking about as a programmer, what I'm thinking about as a programmer
in C Sharp and C++,
things are pretty similar.
If I'm using modern C++,
I don't think about memory management too much
as long as I use the right types.
Okay.
But I guess behind the scenes,
there is a difference.
I think, was it CppCon last year, Herb Sutter?
Did it talk about the memory management in C++?
Introduce new pointer types, that kind of thing of thing yeah yes yeah i remember he had a slide or something with a table that was really excellent
it had you know if i want something to live this scope i do this and this scope i do this and it
kind of broke it down really nicely right um for a developer so i think if you're coming from a
managed language something like that would be really beneficial to kind of understand what are
the what are the idioms in modern c++ for memory management that can avoid the need to, you
know, have dangling pointers and incorrectly freeing things or double freeze and all these
kind of problems you can run into when you're doing kind of like more C-style memory management.
So with IL to CPP, you're taking the IL, you're recompiling it to C++,
so it has some sort of interoperable intermediate layer of some sort so you can bridge these concepts.
How does that work?
So in the C++ code we generate for IL to CPP
does run in a garbage-collected environment.
So it's C++ code,
but we actually are using a garbage collector in our runtime implementation.
Okay.
So the garbage collector is really in the.NET runtime.
So anytime somebody says in C Sharp new,
there's a certain IL instruction,
a single, you know,
if you could call it an assembly instruction,
one instruction IL, which is a new object.
And that's to say,
create an object of this type from the GC.
Okay.
And so that goes to the runtime and says,
GC, I need, you know,
40 bytes of space for this object.
Give me back a pointer with 40 bytes of space.
And any.NET runtime is going to have to do this.
And then it's the job of the runtime and the GC
to keep track of all the references to that thing
and correctly garbage collect it.
But out of CPP, although we're converting to C++
to get the code generation, we're still using a GC.
So it's still a full.NET runtime.
So did you actually, like...
I'm now becoming, like, weirdly curious
about what the actual generated C++ looks like.
Did you, like, make your own operator new and that kind of thing
to generate garbage-collected pointers?
Or are you using allocators?
Or are you just doing something completely different,
like some sort of library implementation?
It's really in a library implementation.
There's a function that gets called into our runtime library,
which says, hey, I need
a new object of this size from the GC.
So it's not an overloaded operator new.
Okay.
So how do you then...
And then, yeah.
I was just wondering how you keep track of lifetime and knowing that, you know, things
are referencing this thing that you just made.
So that's where the garbage collector comes in.
So right now we're using the BOM GC, which is actually written in C.
And Hans BOM, I guess, who's well-known in the C++ community, wrote it, and it's still maintained.
But it's what's called a conservative garbage collector.
So that means that whenever it needs to run a garbage collection, it's going to have to stop all the threads in the program,
and it's going to scan for things that are called GC roots.
It builds a directed graph, basically, of all that memory access is
and all the relationships between objects that it knows about.
The GC roots are what determine what's alive and what's not.
We have the option of allocating specifically, say, this object is a GC root,
and it's going to live for so long in the program.
But it also locates GC roots by looking at the call stack for each thread.
So it'll say, on this thread, look through the call stack,
find all of the local variables that are sitting on the stack.
Any of those that might be references to something which is GC memory, keep track of those.
Okay.
Yeah, so that's really how that works and kind of how we implement the.NET
runtime. And different runtimes and different garbage collectors have different ways to handle that.
Okay. Since we're talking about memory and garbage collection
right now, maybe we could talk about the differences between
constructors and destructors
between the two languages, because I think that's another thing that can be pretty different.
That's true, yeah. So constructors are relatively similar. I mean, the constructor kind of sets up
the invariance for your class or your type, right, the same way in C Sharp and C++. And actually,
it's interesting to kind of see as languages kind of cross-pollinate ideas, right? So C Sharp has had, I think they're called forwarding constructors maybe for a while, where one constructor can call another one.
And I think C++ got that at C++11, which is a really nice feature for kind of organizing class initialization, especially if you want to provide a different interface to initialize a class in different ways.
So in that respect, constructors are pretty similar.
Destructors are very different.
So they're spelled the same way, right?
If you look in code in C Sharp and C++,
you see tilde, you know, type name or something, right,
for both destructors, but they're totally different.
In C Sharp, because it's garbage collected,
there's no guarantee about when an object will be deallocated.
Even if it's no longer referenced at the end of a function or when a class goes out of scope,
the garbage collector may not have an opportunity to actually collect that memory anytime soon.
It's totally non-deterministic.
So the way that works is there's the destructor, which is also called a finalizer in C Sharp sometimes,
will get executed at some arbitrary time.
In some. time. Um,
in some.net runtimes that's at,
that occurs on a background thread.
So for Alta CPP on most platforms,
um,
we have a separate thread that runs that,
that calls finalizable objects and says,
okay,
the garbage collector is done with you.
I can call your finalizer now call your destructor.
Um,
that means in C sharp,
you have to be really careful about what you put in a destructor.
You can't have references to any other objects
that might be on the heap
because they may have been called before or after you.
They're destructors, you don't know.
So you're really restricted.
You know, where C++,
because we have the scope-based,
you know, resolution in RAII,
which is that resource acquisition is initialization.
That acronym always, it's a confusing formula. But basically, right, when you exit a scope, in RAII, which is that resource acquisition is initialization. Yes.
That acronym always is a confusing formula.
But basically, right, when you exit a scope,
the compiler is going to make sure that any types in that scope have the destructors called at a deterministic point, right?
Yes.
So as soon as you leave that scope, they're called,
and they're called in a certain order.
I think based on the order they were declared in that scope.
Reverse order, yeah.
So it's really deterministic.
So the key thing is that difference in determinism.
So in C++, I can have more freedom in a destructor.
I guess still not total freedom, right?
We don't want to do things like throw from destructors.
Sure.
Ugly things like that.
But I can have a lot more freedom in destructor
because I can know and I can reason about
in the code when they'll be called.
So in C Sharp, I can't do that.
So I think for most C Sharp programmers,
I've learned at least that you really don't want to put any code in a finalizer
or a destructor unless absolutely necessary.
That's always like a last resort.
And I know I've been bitten by four by putting code in there
and bugs come up because, oh, I didn't think it'd call it in this case
or at this time or something like that.
I mean, in C Sharp, what code would you put in a destructor
if you have no idea when it's going to execute?
It's really tough.
Sometimes it'll be, a lot of times if it's objects
that have a native or an OS level thing kind of behind the scenes,
they have to manage like a file or a thread or a socket
or something in the OS level that's not part of the managed language system
you'd put there. So if you're all working in a managed code, yeah, you almost never write a destructor. or a socket, or something at the OS level that's not part of the managed language system,
you'd put there.
So if you're all working in a managed code,
yeah, you almost never write a destructor.
But once you start calling into,
you know, pick up these things that don't work with the C Sharp GC,
you may need to say,
if I have a wrapper class that manages a file,
for instance, like I need to make sure that
when the finalizer's called,
if the file handle's still open,
it gets closed, so I don't leak it.
That's
probably the thing I've seen
in most
cases, something like that.
The
one thing that is in C Sharp, which is similar to a C++
destructor, is this
interface called IDisposable.
It has one method called dispose,
and that's kind of a
cleanup method, similar to what a C++ destructor does.
So if you're running C Sharp code,
you can use a pattern with the using keyword,
which basically says, I'm going to use this object,
and this object has to implement IDisposable.
And then when we get, it's an open curly brace,
then a bunch of code.
And at the closing curly brace,
the dispose method will be called.
So you get something like RAII in C Sharp. So if you're a C Sharp
developer, I'm guessing you might be familiar with that
pattern,
with using an IDisposable, and
that you could, in your
mind, that's very similar to what C++ destructors
do.
The whole concept of language is when
I don't know when something's going to be
destructed, it just makes me uncomfortable.
It can be really scary, yeah. And when you get to
working between C Sharp and C++ or working C Sharp with
OS concepts that don't fit into the GC, it can become
you know, there's some odd kind of bugs that can happen there.
Right.
I wanted to interrupt this discussion for just a moment to bring you a word from our sponsors.
Backtrace is a debugging platform that improves software quality,
reliability, and support by bringing deep introspection
and automation throughout the software error lifecycle.
Spend less time debugging and reduce your mean time to resolution
by using the first and only platform to combine symbolic debugging, error aggregation, and state analysis.
At the time of error, Bactres jumps into action, capturing detailed dumps of application and environmental state.
Bactres then performs automated analysis on process memory and executable code to classify errors and highlight important signals such as heap corruption, malware, and much more. This data is aggregated and archived in a centralized object store,
providing your team a single system to investigate errors across your environments.
Join industry leaders like Fastly, Message Systems, and AppNexus
that use Backtrace to modernize their debugging infrastructure.
It's free to try, minutes to set up, fully featured with no commitment necessary.
Check them out at backtrace.io slash cppcast.
Since you brought up just now the two of them working with each other,
what are some of the ways C Sharp and C++ can interoperate?
Well, usually they interoperate like a lot of languages through the C ABI
because C++ doesn't have a stable ABI across compilers.
So there's a method called P invoke or platform invoke,
which I think was originally designed in C Sharp
to access the Win32 API, which is a C API.
But it can really be used for any function
that can be exposed as a C function.
So you can define an extern function in C Sharp
and then apply some attributes to it to tell the runtime, hey, this function maps to some native function in a given DLL or shared object of a given name.
And what happens then, whenever the runtime, C sharp runtime, sees that method called, then you can, it'll say, oh, go look up that native function in that DLL, get a function pointer to it, and invoke that function pointer with the arguments.
And then the arguments have to be mapped or marshaled,
as it's called, from managed code into native code.
So, for example, a string in C Sharp,
most runtimes represent a string as an integer,
which is the length of the string,
followed by UTF-16 encoded 2-byte characters
to make up the content of the string, followed by UTF-16 encoded two-byte characters to make up the content of the string.
And when you go to a C or C++ function with a string as an argument, that has to be copied into a char star, basically.
And the runtime will allocate a buffer for that.
It'll copy all the characters, do a conversion to, I guess, ASCII or UTF-8,
and then provide a pointer to the native code with
that same variable in it, that same data. So what happens there is all the parameters and the return
type have to be marshaled. One kind of interesting caveat that we see a lot in that case is,
for example, functions returning bool make a lot of sense, right? You might want to call into native
code or native library and ask, you know, a question, right? It returns a bool. Well, in C Sharp, a bool is marshaled as a four-byte integer
because the capital B-O-O-L type in Win32 API is four bytes.
Okay.
But in C++, of course, a bool is one byte, right?
Probably, yeah.
So I guess maybe it doesn't have to be.
Yeah, I don't believe there's a requirement, but yes.
Most implementations we've seen have one
byte so i make a function call to a native method which returns me a bool and everything works great
and now i turn on optimizations in my c++ build and uh-oh now like you know that that extra three
bytes that in the you know in the debug build there was nothing was used there and it happened
to be zero or something it worked out now that that's used by something else, and we get the wrong return value.
So we have to explicitly
tell the C Sharp or the
.NET runtime, hey, this
is a bool return value. I want you to treat this
as a one byte unsigned value,
because otherwise you're going to treat this as a four byte
unsigned value. So
when you go from interop from C Sharp to C++,
you kind of get these sort of
odd
little characteristics sometimes.
And you can hit performance problems if you're going across that boundary a lot
because marshalling can be expensive to allocate and deallocate memory on a regular basis.
And you can do the same thing in reverse.
So you can take a C sharp function,
and there's a method in the.NET standard library you can call to get a function
pointer to it a C function pointer oh and then you can pass that C function pointer to native code
somewhere in C or C++ and you could wrap it in a std function or you know whatever you're
whatever you're doing in in C++ or native code and you can call it later and when you execute
that function there's a little wrapper around it that the.NET Runtime has created,
which will say, oh, I see this is a managed method
you're calling, so I'm going to marshal
all the parameters back from native code to managed code.
So again, if you had a char star on that argument list,
it would allocate some managed memory with the GC,
build up a managed string,
and then pass that managed string
into the managed method that you asked to execute.
This all sounds very expensive.
It really is. It really is.
Usually, the pattern that we see for this kind of thing
is if you have some sort of a native library
where you have a high performance, you know,
something that you can implement native code much faster,
you can implement a managed code, right?
And you want to give it a bunch of data.
You say, okay, I'm going to give this native method
some sort of data which is blittable,
meaning that we can just do a direct memory copy
from managed native code,
so a big array of bytes or something like that.
Let's say I want to render something,
and I have to give it to a native rendering code from C Sharp,
so I can give it a big array of bytes,
and it does the work for me and then returns.
So anything that's kind of a chatty interface where you're going back and
forth across this boundary pretty often is usually really expensive.
And the.NET runtime is going to do a lot of work to kind of make that all
happen that you probably don't see in the code immediately.
So, so yeah, but it's really beneficial, right?
If you have, you know, code that's really beneficial, right? If you have
code that's in both managed and native code, or you're
transitioning from one to the other, you know,
in a section of code, the ability to
interoperate between them is, you know,
absolutely necessary.
Right. Okay, so now
I'm curious about IL to
CPP again. We've talked about these
costs, and we've talked about JITing,
and now I'm wondering what the motivation was for making your own.NET runtime with the CPP again. We've talked about these costs and we've talked about jitting. And now I'm wondering
what the motivation was
for making your own.NET runtime
with the C++ translation.
So the motivation was twofold.
First of all,
the biggest one
was probably portability.
And then a secondary one
was performance.
So because we support
so many platforms at Unity,
we're always looking for ways
to make our code more portable. Like the less work we have to do to bring up a new platform, the faster we can get many platforms at Unity, we're always looking for ways to make our code more portable.
The less work we have to do to bring up a new platform,
the faster we can get it to our users,
the faster they can make games in it.
That's really important to us.
IELTS CPP is slightly different from the.NET framework
and.NET Core and even parts of Mono
because it's not a JIT.
It's an AOT compiler ahead of time.
So IELTS CPP does not allow for runtime code execution
like you would get in.NET.
In.NET, I can actually say,
in C Sharp, I can create a method inside code
and then say, okay, go execute this method, right?
ALTA CPP doesn't support that.
It's only ahead of time compilation.
Okay.
So with that in mind,
basically ALTA CPP is converting IL code to C++, Okay. can take I-O code, can A-O-T it, and get machine code directly out without going through a.NET...
without jitting through a.NET runtime.
Okay.
This is really useful for platforms like iOS
and a lot of console platforms
where runtime code execution is not allowed.
You know, the vendors or the operating systems
don't prevent this,
so PlayStation 4, Xbox One,
you know, all these platforms are A-O-T only.
You have to have pre-capable code.
So
the portability aspect is this.
If we wanted to bring up a new platform
at Unity, we had
to have a person who understood the
architecture of the platform,
the OS of the platform,
assembly language for the platform,
and the way that
Mono's AOT engine works.
Okay.
So finding developers with that skill set
is really difficult,
and even ones who are really good at that
would be, you know, basically months
to bring up a new platform sometimes.
There's a lot of work there.
So by taking the IL code and converting it to C++,
now we have this representation of the code C++,
which really works well because it can,
every platform that we have already has a C++ compiler.
Usually those C++ compilers are really good at generating code.
They can generate efficient code.
They can usually generate better than, you know,
handwritten code that someone could write into an AOT engine
because they've got, you know got years and years of developer time put
into them to generate efficient code.
So really it came down to portability.
So we've taken our time to port
our scripting engine
to a new platform
from maybe months to weeks
using Alta CPP.
So basically it means if I'm going to port to a new
platform, I need to
do some back-end code to make sure that there's the C++ runtime section of IELTS to CPP.
We call it lib IELTS to CPP, which is actually just normal C++ code that developers write that runs on the target platform.
That has to be implemented for the target APIs, right?
Sockets, files, threads, mutexes, all these kind of primitives need to exist and someone has to
implement those that's not not too much code though but then all of the i.o code that we have to
actually you know aot down to the machine level from the standard library and from all the user
code that's always the same c++ code across all platforms all the cpp generates you know platform
invariant code, basically.
So that gives us a nice portability win whenever we have to bring up a new platform.
And then we do get, on some platforms,
better AOT code, better machine code output,
because, like I said, the C++ compilers
are usually pretty good at that.
We can pick up wins in a few other places.
We've had benefits where the mono-AOT
had to use double for floating point calculations,
and Unity is mainly a float engine,
so we're getting really over-precision sometimes,
and so some floating point scenarios,
ALDA CPP generates faster code.
Okay.
But the real main focus was on portability
and the ability to bring up new platforms faster.
I'm wondering if it does it at all ease this difficulty in the interoperation between C++
and C sharp code that we were just discussing?
So it really doesn't actually, which is kind of odd.
I thought that it would when I first started here and started working on this.
Oh, this is gonna be really easy, right?
We're emitting C++ code, but it doesn't make it a whole lot easier because even though we're
emitting C++ code, that C++ code is really just, you can think of it as an intermediate
representation for machine code.
I mean, that's what it's going to be.
Right.
And so it still has to follow all the same rules that the machine code has to follow
eventually as far as marshalling of parameters and return values and making sure that things
are correctly hooked up to the managed runtime that we talked about so the interesting thing though is whenever
you whenever you look at the c++ code that's generated by alda cpp for these marshalling
cases and these p invoke cases you can actually see written in code the cost of it you can see
oh look i have to iterate over all of the strings in this array, and I have to allocate code for each one,
and I have to allocate memory for the array,
and I have to copy them all.
Now I make the function call.
And now I come back out of the function call,
and this marshalling scenario may be one of the changes
that remade a native code to be available in managed codes,
and now I have to iterate the array again,
reallocate new entries, copy all the data, and back over.
Whereas when you're just looking
at machine code, that's really hard to see. Right. But it actually does not make the interop
better in a sense of performance. There's all the same work has to be done.
Okay. But you did, you did say that one of the motivations for IAO to CBP is performance,
but the main motivation is portability. So is the generated C++ still something that the C++ compiler can optimize, or is it something
that it's like, I have no idea what you're doing here?
No, the C++ compilers do a really great job of optimizing it.
I was kind of, you know, I've been worried about that in the past, but they seem to do
really well on pretty much every platform we've seen.
Since IL has no flow control,
everything's gotos, so the generated C++
code, it's really IL
that's transpiled, basically.
So you end up with gotos all over the place.
There's no loops.
There's some ifs, that's about it.
But the C++ compilers do a really
good job. And one of the ways
that we benefit is we can
control how much C++ code is in a
translation unit and what goes where.
So we can really get
some nice benefits out of inlining,
especially without link time optimization.
So LTO is really
nice when we're getting to a final product,
especially for something that's
high performance like a game. But for
iterating in development time, LTO can be
really difficult because it can take a long time to do link time optimization.
So one of the things that we do is try to group together managed code
that executes in the same places, like in the same types,
into the same translation units.
And we'll generate really big translation units,
maybe like 50,000, 60,000 lines of C++ code.
Okay.
And so that gives the compiler a lot to chew on
for inlining, for example.
Right.
So we get, on most of the compilers we have,
pretty much all of them,
we get pretty good optimization.
We're very happy with the resulting machine code
that we get out.
That's very interesting.
So IL2CPP works with the C Sharp Unity scripts
for Unity games.
Could a Windows C Sharp developer write an app and choose to compile it with IL2CPP
instead of the visual C Sharp compiler and get some benefit out of that?
Not easily.
I mean, theoretically it's possible.
We can convert pretty much any IL code that came from a C's possible. We can convert pretty much any
ILCode that came from a C Sharp compiler.
We could convert, but
we don't really have it packaged or available like that.
Internally for
testing, we do some things like that,
but our focus
is really on the Unity customers
and not on a general runtime
necessarily, so
it's not available in that respect,
although maybe someday, I don't know.
It's only technically possible.
So why did Unity choose to use C Sharp as a scripting language?
So that's a tough question.
That kind of extends back before my time at Unity.
I think way back when it was just the founders,
I think it may have been Python, actually.
That's a terrible language for embedding.
Yeah, I don't know the technical details,
but I think at some point it was C Sharp and.NET were chosen.
I think a lot of it had to do with Mono being an open source project.
And at this point, you know, I've been, like I said,
10 or 15 years on with Unity.
You know, we're really happy like I said, 10 or 15 years on with Unity.
You know, we're really happy with that decision to use C Sharp because the C Sharp ecosystem has really blossomed,
especially in the last maybe three to five years with Microsoft,
open sourcing a lot of things and really taking a renewed focus on it.
I mean, the C Sharp ecosystem is pretty big.
There's a lot of tools out there that really make it easy for developers to work in C Sharp.
So we like that. And one of the things like the reflection capabilities, you know,
the jitting capabilities we can use in a lot of cases.
We can kind of help users and guide them and protect them so that they can focus on making
a game and not worry about, you know, as I think our CTO said in a recent talk, you know,
the last thing we want is you to be, have this game ready to go, and two days before
it's released, you find some random crash, you know, that you can't track down, right?
That's, we've done something wrong if that happens and the unity side so so our
goal is to you know make it as easy as possible and c-sharp provides a lot of safety and more
safety than you get out of c++ i think in that respect right um so that's really nice but uh
yeah where why it actually originally started i'm not entirely sure i think it probably had to do
with the the fact that mono was open source and was the product that was available that worked well.
Now I feel like I should clarify, just in case I get some hate mail
for saying that Python would be a terrible language to embed.
The Python interpreter was never designed for embedding.
And if you really want to dig into it,
you can look into something called the global interpreter lock,
and it just makes things difficult.
But anyhow.
And that makes sense, too.
That might also go into why Mono was chosen in C Sharp,
is Mono was kind of from the beginning, I think,
designed for embedding.
Yeah.
It can be run standalone,
and it has a really nice embedding API.
So from Unity, we can call and get access
to all of the Mono VM internals
from C and C++ with very little friction.
I've never used Mono specifically, but it's easy for me to believe since it was the same group of people that liked having a Lisp interpreter and Emacs kind of thing.
So it's a lot of GNU guys that were working on it.
Yeah, it's really a great technology.
I mean, you look at all the things that they've done,
it's pretty incredible, actually,
to fully re-implement the.NET ecosystem, basically,
in an open-source way.
Yeah, that's cool.
Is Xamarin also based on Mono?
Yeah, so Xamarin is, well, was a company,
and Xamarin, I guess, is a product now, too,
which is like using the Mono project for mobile development.
But Xamarin was recently acquired by Microsoft.
So from a company perspective, it's part of Microsoft,
but there's still the Xamarin iOS and Android
and maybe a few other products out there.
Going back to Unity and the scripting languages,
you also support JavaScript, right?
Does JavaScript do anything with AltaCPP?
So it does.
We support JavaScript and a language called Boo,
which I think is maybe short for Bamboo.
But one caveat, the JavaScript is not really JavaScript.
It's more like air quotes JavaScript.
We actually call it UnityScript internally. So at one point, maybe years ago, it was JavaScript. It's more like air quotes JavaScript. We actually call it UnityScript
internally.
At one point, maybe years ago, it was JavaScript.
But it was
the way that JavaScript
and Unity, or I'll call it UnityScript just to be clear,
the way that UnityScript works
is it's actually built on top
of this bamboo language, this Boo language.
So the Boo compiler
actually interprets the
UnityScript code and then generates
IL code, which we run on the.NET
runtime.
That's a little bit
out there, right?
So a couple levels there.
But the issue was that as JavaScript evolved,
UnityScript did not evolve with it.
So UnityScript is
kind of like a snapshot of JavaScript
maybe at some point in time.
But we do still support it,
although we're kind of phasing out support for it now
because the C Sharp ecosystem has continued to really evolve
and C Sharp as a language has grown.
There's some new features of C Sharp,
especially in C Sharp 7,
that we want to use in the Unity APIs,
and we can't get support for those in UnityScript
without significant work from our side.
And we think it's better to kind of standardize on one language.
So over the next couple of releases of the Unity 3D game engine,
we'll be phasing out UnityScript support.
We actually have some teams working on tools
that'll convert UnityScript code to C Sharp code,
because there's a lot of user code out there
that still is using UnityScript,
and we want to make sure that those users are supported.
So it's still a possibility.
Sounds like an impressive undertaking,
effectively converting JavaScript to C Sharp.
Yeah, I'm not involved in that,
but it does sound like a lot of fun.
I think it's going to work,
but we have a team working on it now,
and the plan is that UnityScript will be phased out,
so it's still possible to use right now.
But the relationship to IL to CPP is that the bottom line is
UnityScript is compiled onto IL,
so IL to CPP will convert it then
without really caring a whole lot about what the original language was.
Cool.
So that's the benefit of.NET and IL in general.
You can write multiple languages on top of this same IL infrastructure
and kind of share the runtime.
Right.
And we haven't talked much about the other.NET framework languages,
but there's also Fsharp and VB.NET, right?
Would they also be able to compile down to IL and run through IL to CPP?
Parts of them can. Those aren't
officially supported by Unity. We've done some work
with Fsharp kind of internally
to make it work, but there's some
parts of it that are really difficult to implement and require
kind of significant work
in the runtime.
I know that Mono, for instance, supports
all of that, and
they've put a lot of effort into that.
So it's something that,
since they're not officially supported by Unity,
we've not supported an aisle to CPP.
But a lot of the code that you'd get out of VB or Fsharp would work.
But it's not something that you should try as a developer, I don't think,
because unfortunately, if you submit a bug report to Unity,
we'll have to say, well, we don't officially support that,
so we probably can't fix it.
Okay.
Before we let you go,
do you want to just tell us a little bit more about Unity
and maybe getting into game development?
Is this something that an indie developer can pick up
and try out for free?
Absolutely, yeah.
Absolutely.
The whole Unity product is available.
You can get all of our platforms that we support for free.
I think there's a cap on the yearly revenue or something like that, $100,000.
I don't know what it is now. Maybe it's more.
But yeah, you can download it and try it, and I really recommend it.
So I mentioned one of the things that we try to do is solve hard problems.
Another kind of key tenet for Unity is democratization of game development.
The idea is to make it that anybody who wants to make a game can.
Now, I really, you know,
since working in the games industry
for the past few years,
I've come to a great respect for game developers
because it's not an easy task.
I mean, balancing coding, artwork, sound effects,
you know, performance optimization,
you know, understanding different devices
and architectures,
there's really a lot there.
Right. And, you know, and then not even counting like backend things like servers understanding different devices and architectures. There's really a lot there.
And then not even counting back-end things like servers and analytics
and all these things you need to make a successful game.
It's pretty amazing how people do it.
But yeah, anyone who wants to get started,
Unity3D.com is the website.
They can download it and give it a try.
Well, and since we're talking to a bunch of C++ developers here,
we talked about using UnityScript and C Sharp
for effectively writing your Unity game.
Can we use C++ to write a game with Unity also?
Yeah, it's possible.
The Unity API is not available in C Sharp,
so you're going to be restricted in what you can do.
You mean not available in C++?
Sorry.
Thank you. Yes, you're right. I got mixed up. Yes, not available in C++. So the You mean not available in C++? Sorry. Thank you. Yes, you're right.
I got mixed up.
Yes.
Yeah, not available in C++.
So the API is only available in C Sharp.
Interesting.
So places where you need to interact with Unity,
you have to use C Sharp.
But, you know, it's not uncommon for games
to have significant parts of their code
that are native code, even with Unity.
Okay.
So if you're looking for, you know,
something where you want to write it in native code,
you know, that's certainly possible.
Now, one of the kind of cool things that we have coming up on the horizon,
which I'm not directly involved in,
but I've seen it at our conferences and whatnot,
is kind of a...
What's the best way to describe it?
It's kind of a new idea for thinking about high-performance code in C Sharp.
So the idea is to take the garbage
collector out of the equation, provide a native like memory management. So I can say I want,
you know, arrays and lists and sets of memory, which is contiguous and really take a data oriented
design view so that I can, I can, I can set up all my memory the way I want. I don't have to
worry about the GC putting it in a different place or moving it or anything like that. I set it up how I want.
I can now
spread out my computations and my tasks
across many different
threads or cores on a machine
and do this all from C Sharp.
Our goal is to say,
we can get as good or better
performance than we can with native languages in some respects.
So you can do, so that's coming down the line,
I think maybe in the next Unity release
or the next one after that.
But it'd be something to check out,
especially if you're a developer working on,
you know, in native code for performance.
Okay, you know, it might be a trade-off
if you want to take a look at it.
Do I get, you know, as good a performance
in a managed language?
Maybe I get a little more safety, or do I want to stick with a at. Do I get as good a performance in a managed language? Maybe I get a little more safety
or do I want to stick with a native language where I'm closer
to the machine, but
I may have a little bit more that I have
to manage on my own.
Okay. Well, thank you so much for your time today, Josh.
Where can people find you online?
My blog is
joshpeterson.github.io
and petersonjm1 on Twitter.
And also check out the Unity 3D blog.
We've got a lot of content up there for game developers.
About two years ago,
I did a series about IELTS CPP internals.
So if you're interested in seeing
how the C++ code gets generated
and some of the things we discussed, it's there.
And there's another kind of mini-series
that we did about a few optimizations
that the IELTS CPP Plus transpiler makes.
Now, it doesn't do many, but it does a few things to try to optimize the code based on
the knowledge it has.
So those might be something to take a look at if you're interested.
Cool.
Great.
Thanks so much for your time today.
Yeah, thanks for joining us.
Thank you.
I enjoyed it.
Thanks so much for listening in as we chat about C++.
I'd love to hear what you think of the podcast.
Please let me know if we're discussing the stuff you're interested in, or if you have a suggestion for
a topic, I'd love to hear about that too. You can email all your thoughts to feedback at cppcast.com.
I'd also appreciate if you like CppCast on Facebook and follow CppCast on Twitter. You
can also follow me at Rob W. Irving and Jason at Leftkiss on Twitter. And of course, you can find all that
info and the show notes on the podcast website at cppcast.com. Theme music for this episode is
provided by podcastthemes.com.