import std.stdio, std.range, std.algorithm, std.compiler, core.bitop;
// Optimizing compilers should do tail call optimization here, so
// 0xBADF00D magic constant won't be found in stack if optimizations
// are enabled. Is there a cleaner way to detect optimizations?
bool detect_opt() {
int[100] filler;
bool detect_tail_call_opt(int depth, int magic) {
if (depth > 100) {
int x; foreach (i ; 20 .. 80) if (*(&x + i) == magic) return false;
return true;
}
return detect_tail_call_opt(depth + 1, magic);
}
return filler[0] || detect_tail_call_opt(0, 0xBADF00D);
}
// GDC11 was the first version to start supporting getTargetInfo traits
bool detect_gdc11() {
version(GNU) { return __traits(compiles, __traits(getTargetInfo, "cppStd")); }
else return false;
}
// GDC inline assembly for RDTSCP instruction (works only on x86 hardware)
ulong rdtscp(ref uint coreid)
{
uint hi, lo;
version (GNU) {
asm { "rdtscp" : "=d" (hi), "=a" (lo), "=c" (coreid); }
return (cast(ulong)hi << 32) + lo;
} else {
assert(false);
}
}
bool detect_templates_inlining()
{
uint coreid1, coreid2;
ulong before, after, time1 = ulong.max, time2 = ulong.max;
size_t repeats = 100, counter = 1000, ans1, ans2;
foreach (i ; 0 .. repeats) {
volatileStore(&before, rdtscp(coreid1));
size_t max_x = volatileLoad(&counter);
size_t ans = iota(1, max_x + 1).map!(x => x * x ^ x).sum;
volatileStore(&ans1, volatileLoad(&ans1) + ans);
volatileStore(&after, rdtscp(coreid2));
if (coreid1 == coreid2)
time1 = min(time1, volatileLoad(&after) - volatileLoad(&before));
}
foreach (i ; 0 .. repeats) {
volatileStore(&before, rdtscp(coreid1));
size_t max_x = volatileLoad(&counter);
size_t ans = 0;
for (size_t x = 1; x <= max_x; x++)
ans += x * x ^ x;
volatileStore(&ans2, volatileLoad(&ans2) + ans);
volatileStore(&after, rdtscp(coreid2));
if (coreid1 == coreid2)
time2 = min(time2, volatileLoad(&after) - volatileLoad(&before));
}
if (ans1 != ans2)
assert(false);
return time1 / time2 < 2;
}
void main() {
bool assert_on = false, optimizations_on = detect_opt();
version(assert) { assert_on = true; }
string[] warnings;
version(GNU) {
writefln("Detected compiler: GDC (frontend v%d.%d)", version_major, version_minor);
if (!optimizations_on)
warnings ~= "Performance warning: '-O2' or '-O3' option was not used!";
if (assert_on)
warnings ~= "Performance warning: '-frelease' option was not used!";
if (detect_gdc11()) {
if (!detect_templates_inlining()) {
warnings ~= "Performance warning: '-flto' or '-fno-weak-templates' option was not used!";
}
}
} else version(LDC) {
writefln("Detected compiler: LDC (optimizing for %s)", __traits(targetCPU));
if (!optimizations_on)
warnings ~= "Performance warning: '-O' option was not used!";
if (assert_on)
warnings ~= "Performance warning: '-release' option was not used!";
if (__traits(targetCPU) == "pentium4")
warnings ~= "Performance warning: '-mcpu=native' option was not used!";
} else version(DigitalMars) {
writeln("Detected compiler: DMD");
if (!optimizations_on)
warnings ~= "Performance warning: '-O' option was not used!";
if (assert_on)
warnings ~= "Performance warning: '-release' option was not used!";
warnings ~= "Performance warning: DMD generates much slower code than GDC or LDC!";
} else {
warnings ~= "Unknown compiler";
}
if (size_t.sizeof < 8)
warnings ~= "Performance warning: not a 64-bit compiler!";
if (warnings.empty)
writeln("Everything seems to be properly configured.");
else
writeln(warnings.joiner("\n"));
}
Write, Run & Share D language code online using OneCompiler's D language online compiler for free. It's one of the robust, feature-rich online compilers for D language. Getting started with the OneCompiler's D language compiler is simple and pretty fast. The editor shows sample boilerplate code when you choose language as D and start coding.
D language is a general purpose object oriented programming language similar to C in syntax created by Walter Bright and released in 2001. Dlang is more powerful than C++ as it has gained good features from C++ and also has additional features added.
datatype variable-names;
When ever you want to perform a set of operations based on a condition If-Else is used.
if(conditional-expression) {
//code
}
else {
//code
}
You can also use if-else for nested Ifs and If-Else-If ladder when multiple conditions are to be performed on a single variable.
For loop is used to iterate a set of statements based on a condition.
for(Initialization; Condition; Increment/decrement){
//code
}
While is also used to iterate a set of statements based on a condition. Usually while is preferred when number of iterations are not known in advance.
while (condition) {
// code
}
Do-while is also used to iterate a set of statements based on a condition. It is mostly used when you need to execute the statements atleast once.
do {
// code
} while (condition);
Array is a collection of similar data which is stored in continuous memory addresses. Array values can be fetched using index. Index starts from 0 to size-1.
data-type array-name [ array-size ];
Function is a sub-routine which contains set of statements. Usually functions are written when multiple calls are required to same set of statements which increases re-usuability and modularity.
return_type function_name(parameters) {
//code
}
function_name (parameters)