Architecture is not JUST for brain limitations. Dividing a large task into separate testable (and formally provable now that we have AI to do the immense labor this takes) modules interconnected by message passing through shared memory with an eye towards performance is architecture.
It’s not simple either, for example performance requires someone or something to have a flow graph in their head or represented somewhere to know where the bottlenecks are.
I agree with you on the idea of AI bytecode authors: once you have a program into a representation tight enough that one and only one binary truth table can be constructed to model the behavior of the program (a property all programming languages have while English doesn’t), a second AI could just write the bytecode or fpga logic in an optimized form.
No need for compilers, the language could be python or higher where all languages below that are pointless.
Architecture is not JUST for brain limitations. Dividing a large task into separate testable (and formally provable now that we have AI to do the immense labor this takes) modules interconnected by message passing through shared memory with an eye towards performance is architecture.
I would think that this part is one of the easier ones to automate. If you don’t see it that way, what do you feel the impediments that require human input would be?
Edit:
once you have a program into a representation tight enough that one and only one binary truth table can be constructed to model the behavior of the program
Note that this is not quite the case already: different compilers or different versions of the same compiler, or different optimization levels of the same version output different binaries even on the same platform, let alone on x86 vs ARM or something! There are best-effort promises of “one binary truth table” but it is never a guarantee.
This means the top level of the program (what it will output given binary input I) produces the same behavior, which is true for all languages.
This is definitely not my experience, having worked with C in embedded systems for some decades. Every new port has at least slightly different behavior, which sometimes matters and sometimes does not. Some of the things that tend to break: timing, especially in a multitasking system, creating or exacerbating race conditions; values in memory left uninitialized (probably not as much of an issue for more modern languages, though I have seen this in Java as well); garbage collection (say, in JS when switching browsers); implementations of markup (breaks all the time for no reason).
Output = f(I) can be represented by a truth table with a row for all permutations of I.
I have a substantial amount of embedded systems experience. More than 10 years.
Note that what you are describing is almost always in fact faulty system behavior which is exactly the reason you need better architectures. Many systems shipping today have faulty behavior, it passes acceptance tests but is undefined for the reasons you mention.
Determinism and timing guarantees is almost always correct software behavior. (RNGs being isolated exceptions)
We could not fix the architecture for many systems for the obvious reasons, the cost in labor to rewrite it. Which disappears if you can ask an AI to do it in a series of well defined steps.
Just to specify my claim a little harder, I am saying that individual threads/ISRs/processes/microservices: every actor has an initial input state, I.
And then the truth table rule above applies.
If a thread hits a mutex, and then either waits or proceeds, that mutex state is part of the truth table row.
Depending on when it got the lock and got to read a variable, the variable it actually read is still part of the same row.
Any internal variables it has are part of the row.
Ultimately for each actor, it is still a table lookup in practice.
Now as I mentioned earlier, this is generally bad design. Pure functional programming, which at all levels of embedded systems up to hyperscaler systems, has become the modern standard, and even low level embedded systems should be pure functional. This means they might hold a reader and writer lock on the system state they are modifying, for example, or other methods so that the entire state they operate on is atomic and coherent.
For example I’ve written a 10 khz motor controller, where it is a functional system of
PWM_outputs = f( phaseA, phaseB, resolver, PID_state, speed_filter[], current_filter[]) and a few other things. My actual implementation wasn’t so clean and the system had bugs.
This above system is atomic, I need all variables to be from the same timestep and if my code loop is too slow to do all the work before the next timestep, I need to release control of the motor (open all the gates) and shut down with an error.
If I had an AI to do work for me I would have asked it to do some fairly massive refactors and add more wrapper layers etc and then self review it’s own code by rubrics to make something clean and human readable.
All things that GPT-4 can do right now, especially if it gets a finetune on coding.
Architecture is not JUST for brain limitations. Dividing a large task into separate testable (and formally provable now that we have AI to do the immense labor this takes) modules interconnected by message passing through shared memory with an eye towards performance is architecture.
It’s not simple either, for example performance requires someone or something to have a flow graph in their head or represented somewhere to know where the bottlenecks are.
I agree with you on the idea of AI bytecode authors: once you have a program into a representation tight enough that one and only one binary truth table can be constructed to model the behavior of the program (a property all programming languages have while English doesn’t), a second AI could just write the bytecode or fpga logic in an optimized form.
No need for compilers, the language could be python or higher where all languages below that are pointless.
I would think that this part is one of the easier ones to automate. If you don’t see it that way, what do you feel the impediments that require human input would be?
Edit:
Note that this is not quite the case already: different compilers or different versions of the same compiler, or different optimization levels of the same version output different binaries even on the same platform, let alone on x86 vs ARM or something! There are best-effort promises of “one binary truth table” but it is never a guarantee.
This means the top level of the program (what it will output given binary input I) produces the same behavior, which is true for all languages.
Output = f(I) can be represented by a truth table with a row for all permutations of I.
Implementation details don’t matter.
Multithreading / runtime delays can change the sequence things output but not the possibility space of outputs.
This is definitely not my experience, having worked with C in embedded systems for some decades. Every new port has at least slightly different behavior, which sometimes matters and sometimes does not. Some of the things that tend to break: timing, especially in a multitasking system, creating or exacerbating race conditions; values in memory left uninitialized (probably not as much of an issue for more modern languages, though I have seen this in Java as well); garbage collection (say, in JS when switching browsers); implementations of markup (breaks all the time for no reason).
We must be living in different worlds...
I have a substantial amount of embedded systems experience. More than 10 years.
Note that what you are describing is almost always in fact faulty system behavior which is exactly the reason you need better architectures. Many systems shipping today have faulty behavior, it passes acceptance tests but is undefined for the reasons you mention.
Determinism and timing guarantees is almost always correct software behavior. (RNGs being isolated exceptions)
We could not fix the architecture for many systems for the obvious reasons, the cost in labor to rewrite it. Which disappears if you can ask an AI to do it in a series of well defined steps.
Just to specify my claim a little harder, I am saying that individual threads/ISRs/processes/microservices: every actor has an initial input state, I.
And then the truth table rule above applies.
If a thread hits a mutex, and then either waits or proceeds, that mutex state is part of the truth table row.
Depending on when it got the lock and got to read a variable, the variable it actually read is still part of the same row.
Any internal variables it has are part of the row.
Ultimately for each actor, it is still a table lookup in practice.
Now as I mentioned earlier, this is generally bad design. Pure functional programming, which at all levels of embedded systems up to hyperscaler systems, has become the modern standard, and even low level embedded systems should be pure functional. This means they might hold a reader and writer lock on the system state they are modifying, for example, or other methods so that the entire state they operate on is atomic and coherent.
For example I’ve written a 10 khz motor controller, where it is a functional system of
PWM_outputs = f( phaseA, phaseB, resolver, PID_state, speed_filter[], current_filter[]) and a few other things. My actual implementation wasn’t so clean and the system had bugs.
This above system is atomic, I need all variables to be from the same timestep and if my code loop is too slow to do all the work before the next timestep, I need to release control of the motor (open all the gates) and shut down with an error.
If I had an AI to do work for me I would have asked it to do some fairly massive refactors and add more wrapper layers etc and then self review it’s own code by rubrics to make something clean and human readable.
All things that GPT-4 can do right now, especially if it gets a finetune on coding.