My new Dell C6100 has arrived.
This is a 4 blade
blade-server type setup. It's got 4 blades, which operate as completely
independent computers with some shared hardware, like the harddrive
back-plain, shared power supplies, and cooling infrastructure.
Each blade has 6 2.5 inch harddrive bays, for a total of 24.
Each blade has 2 Intel Xeon processors. Each processor has 6 full cores, supporting 12 simultaneous hyper-threads, for a total of 24 cores per blade.
Each blade supports a maximum of 96 gigs of ram, with this particular server populated with 48 GB of ram per blade via 6x 8GB chips.
Each blade supports 1 small form-factor PCI expansion card. Not sure what I'll be adding.
Front view.
Top view
Side view
Back
Interestingly, each of the four blades can be individually ejected, even
while the others are powered on and in use. Same with the power
supplies, allowing for continuity of service
First view of the inside.
Popped out one of the power supplies. Upside down view of the label.
The connector supplies power to the motherboard.
Power cable goes here! They provide a nice little handle that you can use to pop it out.
Each blade can be pulled out individually, and here's how it looks.
Two x two blades
Here's the connectors for the power supplies.
Power supplies just hanging out.
Motherboard connection to the shared power bus.
Cleaned up the cable management a bit after I took the other pictures.
Saturday, February 21, 2015
Sunday, February 1, 2015
Pointer conversion between C++ template instantiations
A follow up to my prior entry : http://cogito.jonesmz.com/2015/01/type-conversion-between-c-template.html
That entry detailed template meta-programming techniques to allow for two otherwise not related template classes to be converted from one to another. Sadly, that technique doesn't allow for the C++ type system to convert from, say, Foo<T>* to Foo<U>*. Despite having the appropriate conversion functions to construct new instances of Foo<T> out of Foo<U>, this doesn't give us the ability to treat an existing pointer to Foo<T> as a pointer to Foo<U>, the two classes might have completely different implementations, different v-tables, different memory layouts, and in general be incompatible. Thus, trying to convert a pointer to Foo<T> to a pointer to Foo<U> is impossible, as the C++ type system simply isn't designed to make that a possibility, no matter how many conversion functions you try to apply.
But there is one trick that can help in some situations, by having a template class inherit from a different instantiation of itself!
A quick example, which uses some template metaprogramming techniques.
template<typename T>boost::mpl::empty_base is simply a POD struct that contains nothing, making inheriting from it a non-issue.
class Foo : public boost::conditional< boost::is_const<T>::value
, boost::mpl::empty_base
, Foo<const T> >::type
{
}
Any instantiation of Foo, Foo<T> where T is non const will be legal, and the resulting class will contain all of the members of both instantiations (with the appropriate inheritance rules), just as if the public foo<const T> were instead bar<const T>.
Any instantiation of Foo, Foo<T> where T is const will be legal, but will inherit from boost::mpl::empty_base, which contains no data or member functions, and will not inherit from any other instantation of Foo.
This technique provides us with a mechanism to allow in-place conversion of pointers between the two template instantiation.
In other words
Foo<T> * bar = new Foo<T>();Is fully legal, because any Foo<T> IS-A Foo<const T> by virtue of inheritance!
Foo<const T> * baz = bar;
Of course, this doesn't then permit
Foo<const T> * bar = new Foo<T>();Without a cast, just like we normally need when going from a base-class to a derived-class.
Foo<T> * baz = bar; // WRONG
If you're willing to introduce a few specializations, we can get some much more interesting behavior, such as the non-const version delegating to the const-version's methods if and only if we have both.
template<typename T, typename = void>With that pattern, pointer conversion from non-const->const will work properly, and classes that use the non-const version of functions will delegate to the const version of functions
class Foo
{
bar function1(T) = 0;
void function2(baz) = 0;
}
template<typename T, typename boost::enable_if< boost::is_const<T>::value >::type >
class Foo
{
bar function1(T) = 0;
T function2(baz) = 0;
}
template<typename T, typename boost::disable_if< boost::is_const<T>::value >::type >
class Foo : public Foo<const T>
{
bar function1(T)
{ return Foo<const T>::function1(T); }
T function2(baz)
{ return Foo<const T>::function2(baz); }
}
Subscribe to:
Posts (Atom)