Crossing beams cause excessive compile time, and finally crash #280

Closed
bmcage opened this Issue Feb 19, 2013 · 12 comments

Comments

Projects
None yet
6 participants
Contributor

bmcage commented Feb 19, 2013

Here a script, which is a bunch of beams.
It compiles fine.
Now change parameter
second_skew = 160;
into
second_skew = 180;
and it no longer succeeds to compile. Somehow, all the beams crossing in a single point cause big problems.

scad file:

// Licence: Creative Commons, Attribution
// Created: 16-02-2013 by bmcage http://www.thingiverse.com/bmcage

// An attempt at customizable math art: Stick Bowl

//Make it a bowl or not
add_bottom = "no"; //[yes, no]
//If a bowl, size of the bottom
bottom_height = 1; //[1:20]

//Form of the sticks to use
base_form = "beam"; // [beam, cylinder, hexagon, triangle]
//Size of the sticks
size = 2; //[1:20]

//start radius
r0 = 2; //[2:200]

// number of sticks per ring
nrsticks = 24; //[4:50]
grad_per_stick = 360 / nrsticks;

// radius of the first ring
first_radius = 50; // [0:200]
// extend beyond radius of first sticks
first_extend = 1; //[0:100]
//how skewed (rotated) first ring is in degrees
first_skew = 0; //[-360:360]
// height if the first ring
first_height = 0; // [0:300]

// radius of the second ring (0 for no ring)
second_radius = 50; // [0:200]
// extend beyond radius of first sticks
second_extend = 1; //[0:100]
//how skewed (rotated) first ring is in degrees
second_skew = 160; //[-360:360]
// height if the first ring
second_height = 120; // [0:300]

// radius of the second ring (0 for no ring)
third_radius = 0; // [0:200]
// extend beyond radius of first sticks
third_extend = 2; //[0:100]
//how skewed (rotated) first ring is in degrees
third_skew = -360; //[-360:360]
// height if the first ring
third_height = 120; // [0:300]

// radius of the second ring (0 for no ring)
fourth_radius = 0; // [0:200]
// extend beyond radius of first sticks
fourth_extend = 1; //[0:100]
//how skewed (rotated) first ring is in degrees
fourth_skew = 9; //[-360:360]
// height if the first ring
fourth_height = 1; // [0:300]

// radius of the second ring (0 for no ring)
fifth_radius = 0; // [0:200]
// extend beyond radius of first sticks
fifth_extend = 2; //[0:100]
//how skewed (rotated) first ring is in degrees
fifth_skew = -27; //[-360:360]
// height if the first ring
fifth_height = 20; // [0:300]

// radius of the second ring (0 for no ring)
sixth_radius = 0; // [0:200]
// extend beyond radius of first sticks
sixth_extend = 5; //[0:100]
//how skewed (rotated) first ring is in degrees
sixth_skew = 90; //[-360:360]
// height if the first ring
sixth_height = 40; // [0:300]

use <MCAD/regular_shapes.scad>;
use <utils/build_plate.scad>;

//for display only, doesn't contribute to final object
build_plate_selector = 0; //[0:Replicator 2,1: Replicator,2:Thingomatic,3:Manual]

//when Build Plate Selector is set to "manual" this controls the build plate x dimension
build_plate_manual_x = 100; //[100:400]

//when Build Plate Selector is set to "manual" this controls the build plate y dimension
build_plate_manual_y = 100; //[100:400]

//build_plate(build_plate_selector,build_plate_manual_x,build_plate_manual_y);

bottomstart = -bottom_height; //-first_extend*first_radius/sqrt(pow(first_height,2)+pow(first_radius,2));

module baseform(length){
if (base_form == "beam") {
translate([-size/2, -size/2, 0]) cube(size=[size, size, length]);
}
if (base_form == "cylinder") {
cylinder(r=size, h=length, $fn=20);
}
if (base_form == "hexagon") {
linear_extrude(height=length) hexagon(size);
}
if (base_form == "triangle") {
linear_extrude(height=length) triangle(size);
}
}

module ringbaseform(r1, h1, skew1, r2, h2, skew2, extend){
// a form with correct length if first ring is at r1, h1, and
// second at r2, h2, and extend is extend
//
// P = (r1, 0, h1), Q = (r2 cos(skew2), r2 sin(skew2), h2)
// dir_new = (P-Q) / norm(P-Q) = (a,b,c)
// rotate to new direction, euler angles
// th_x = atan2(b,c); th_y = atan(-a, sqrt(b_b+c_c)) ; th_z = 0
rotate([0,0,skew1])
translate([r1, 0, h1])
help_ringbaseform(r2_cos(-skew2)-r1, r2_sin(-skew2), h2-h1, extend);
}

module help_ringbaseform(a, b, c, extend)
{
rotate([atan2(b/sqrt(pow(a, 2) + pow(b, 2) + pow(c, 2)),
c/sqrt(pow(a, 2) + pow(b, 2) + pow(c, 2))), 0, 0])
rotate([0, atan2(a/sqrt(pow(a, 2) + pow(b, 2) + pow(c, 2)),
sqrt(b_b/(pow(a, 2) + pow(b, 2) + pow(c, 2))
+c_c/(pow(a, 2) + pow(b, 2) + pow(c, 2)))), 0])
translate([0,0,-extend])
baseform(sqrt(pow(a, 2) + pow(b, 2)
+ pow(c, 2)) + 2*extend);
}

module ring(ringnr){
union()
{
for (i = [0:nrsticks]) {
rotate([0,0,i*grad_per_stick]) {
if (ringnr == 1) {
ringbaseform(r0, 0, 0, first_radius, first_height,
first_skew, first_extend);}
if (ringnr == 2){
ringbaseform(first_radius, first_height, first_skew,
second_radius, second_height, second_skew,
second_extend);}
if (ringnr == 3)
ringbaseform(second_radius, second_height,
first_skew + second_skew,
third_radius, third_height, third_skew,
third_extend);
if (ringnr == 4)
ringbaseform(third_radius, third_height,
first_skew + second_skew + third_skew,
fourth_radius, fourth_height, fourth_skew,
fourth_extend);
if (ringnr == 5)
ringbaseform(fourth_radius, fourth_height,
first_skew + second_skew + third_skew + fourth_skew,
fifth_radius, fifth_height, fifth_skew,
fifth_extend);
if (ringnr == 6)
ringbaseform(fifth_radius, fifth_height,
first_skew + second_skew + third_skew + fourth_skew + fifth_skew,
sixth_radius, sixth_height, sixth_skew,
sixth_extend);
}
}
}
}

module bottom(){
if (add_bottom == "yes") {
translate([0,0,bottomstart])
cylinder(r = r0+size, h=bottom_height);
}
}

module bowl(){
union()
{
bottom();
ring(1);
if (second_radius > 0) {
ring(2);}
if (third_radius > 0) {
ring(3);}
if (fourth_radius > 0) {
ring(4);}
if (fifth_radius > 0) {
ring(5);}
if (sixth_radius > 0) {
ring(6);}
}
}

//bowl();
difference(){
bowl();
translate([-250,-250,-500+bottomstart]) cube(size=[500,500,500]);
}

AnHardt commented Mar 19, 2014

Here (Win64 OpenSCAD release: 2014.03) the model compiles perfectly.

Owner

t-paul commented Mar 19, 2014

With the parameter changed to 180 it still crashes for me in render mode (Linux / 2014.03).

The script references a script "utils/build_plate.scad", not sure if that is needed for something important. I can't find that anywhere in the references thingiverse models.

Well, interesting 5 days observing this.
On W7/64 with parameter set to 180 it does not crash at least up to after 4 days (or ~90 CPU hours - using 100% of one 2.53GHz core most of the time) when I gave up.
It just kept using memory, up to about 3.5GB (commit size ie virtual memory space), peak working set (pages in RAM) up to ~1.8GB. That was slow accumulation, 1.2GB after Day 1, 1.75GB D2,3.1GB D3, so could be a memory leak.
All while sitting on 985/1000 of rendering.
BTW, if you're thinking of setting priority to Real-time, I don't recommend it. If you ever do, set Task Manager to Real-time first. It is a PITA to move you mouse once every 5 minutes...I was trying to ensure OpenSCAD got all of one CPU...
But that did give some insight to what OpenSCAD was doing, to me it seems it was in a tight CPU loop, and was only relinquishing CPU (probably some simple system call, or maybe needing more memory) ever 5 min or so.
I would have thought that even if the workload was exponential, it would have got through it in 4 days...
Since clicking on Cancel, it has now been 12 CPU hours without any reaction (the button did its usual animation so I know It pressed). Still using 100% of a core and its commit size is increasing (3.6GB), I'll leave it running a bit longer.

So I think it is more likely a bug, than just a performance issue.

Using process explorer, I can see the stack, but little usable info.

There seems to be two representative types of stack captured.
One:

ntoskrnl.exe!KeWaitForMultipleObjects+0xc0a
ntoskrnl.exe!KeAcquireSpinLockAtDpcLevel+0x732
ntoskrnl.exe!KeWaitForSingleObject+0x19f
ntoskrnl.exe!_misaligned_access+0xba4
ntoskrnl.exe!_misaligned_access+0x1821
openscad.exe+0xe1213
openscad.exe+0xf274a
openscad.exe+0xe47f5
openscad.exe+0xe270d
openscad.exe+0xf9621
openscad.exe+0xf9b20
openscad.exe+0xfa989
openscad.exe+0xf1c96
openscad.exe+0xf1a1f
openscad.exe+0xe28c2
openscad.exe+0xdcfbc
openscad.exe+0xdf3fa
openscad.exe+0xe05af
openscad.exe+0xdc5a2
openscad.exe+0xdb4b5
openscad.exe!g_unichar_fully_decompose+0x942301
openscad.exe!g_unichar_fully_decompose+0xa9f29c
openscad.exe!g_unichar_fully_decompose+0x962155
openscad.exe!g_unichar_fully_decompose+0x9102eb
openscad.exe!g_unichar_fully_decompose+0x90aa79
openscad.exe!g_unichar_fully_decompose+0x90a980
openscad.exe!g_unichar_fully_decompose+0x962d54
openscad.exe!g_unichar_fully_decompose+0x8e3536
openscad.exe!g_unichar_fully_decompose+0xa9ba56
openscad.exe+0xc87fe
openscad.exe+0xb556e
openscad.exe+0xb57ae
openscad.exe+0xb5a40
openscad.exe+0x4f8be
openscad.exe+0x4f80e
openscad.exe+0x4f9f9
openscad.exe+0xb3397
openscad.exe+0xd0705
openscad.exe+0xd9075
openscad.exe!g_unichar_fully_decompose+0x6be678
openscad.exe!g_unichar_fully_decompose+0x73fbf3
msvcrt.dll!srand+0x93
msvcrt.dll!ftime64_s+0x1dd
kernel32.dll!BaseThreadInitThunk+0xd
ntdll.dll!RtlUserThreadStart+0x21

Two:

ntoskrnl.exe!KeWaitForMultipleObjects+0xc0a
ntoskrnl.exe!KeAcquireSpinLockAtDpcLevel+0x732
ntoskrnl.exe!KeWaitForSingleObject+0x19f
ntoskrnl.exe!_misaligned_access+0xba4
ntoskrnl.exe!_misaligned_access+0x1821
openscad.exe+0xe9683
openscad.exe+0xe6251
openscad.exe+0xdd386
openscad.exe+0xee3f6

Of note is frequent calls like ntoskrnl.exe!_misaligned_access+0xba4
this says "Misaligned memory accesses can incur enormous performance losses on targets that do not support them in hardware" so misaligned structs etc could explains some performance hits. But I get an impression it could be involved with paging.

God knows what it is doing with unicode at that point?

Anyway, another unfathomable bug...

hmm unicode, maybe it is trying to generate an error....

Well after 1/2 hour in process monitor openscad generated zero system calls, so it is in a loop.

edit/ a bit later it did a page file read (90 reads in 0.1s), so I suspect that is what periodically allowed me to move the mouse when it was in Real-time priority, but that doesn't indicate it is not just in a loop
/edit
edit/ yep every 6 minutes it pages /edit

Owner

kintel commented Jan 22, 2015

With the latest development snapshot, the problematic version renders (F6) in ca. 50 seconds.
@bmcage Could you give it a spin?

Works for me (set to 180). F6 1m2s.

Don't want to open a can of worms, but if I do 2 consecutive F6s they take the same time???

Owner

kintel commented Jan 22, 2015

It shouldn't, unless your cache size is set smaller than the resulting object size 23MB on my machine.

You're right again, I had reduced my cache for some reason. Now 2nd F6 is 0m0s.

ingegno commented Jan 31, 2015

Yes, It compiles in under a minute now. Good job! This is fixed.

Contributor

bmcage commented Jan 31, 2015

Sorry, was on the account of my wife. As I said, fixed

bmcage closed this Jan 31, 2015

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment