a C++ program that loads over 1 billion records into memory? - c++

I have a whole years worth of option prices in a database (along with other bits of information such as strike price, volatility etc) and would like to load it into memory for my program to process (hash maps, program was written in C++). The trouble is it takes over 10 hours to load into memory at startup (from a local database).
Can someone please suggest how i can overcome this issue ? I have workarounds where i only load the portions that i need but it would be great if people can share ideas to the problem. Would loading the data from shared memory after each startup help?
Here is the code so far, in short it queries the database and loads the data into containers
const std::string m_url = "mysql://localhost/test2?user=root&password=";
URL_T optionURL = URL_new(m_url.c_str());
ConnectionPool_T optionPool = ConnectionPool_new(optionURL);
ConnectionPool_setInitialConnections(optionPool,1);
ConnectionPool_setMaxConnections(optionPool,1);
ConnectionPool_start(optionPool);
Connection_T con = ConnectionPool_getConnection(optionPool);
ResultSet_T result = Connection_executeQuery(con,
"SELECT DISTINCT(underlying) FROM Options");
PreparedStatement_T prepareStatement = Connection_prepareStatement(con,"SELECT underlying,underlyingPrice,expiry,strike,issueDate,type,delta,volatility FROM Options o,RiskFreeRate r WHERE underlying = ? AND o.issueDate = r.date");
while(ResultSet_next(result))
{
const std::string symbol = ResultSet_getString(result,1);
PreparedStatement_setString(prepareStatement,1,symbol.c_str());
ResultSet_T resultDetail = PreparedStatement_executeQuery(prepareStatement);
while(ResultSet_next(resultDetail))
{
float strike = ResultSet_getDouble(resultDetail,4);
date expiry = from_string(ResultSet_getString(resultDetail,3));
std::string issueDate = ResultSet_getString(resultDetail,5);
float underlyingPrice = ResultSet_getDouble(resultDetail,2);
float riskFreeRate = 4; //tmp hack
float volatility = ResultSet_getDouble(resultDetail,8);
OptionDateMap optionMap = m_optionMap[symbol];
OptionVec optionVec = optionMap[issueDate];
optionVec.push_back(boost::shared_ptr<WallStreet::FixedIncome::Option::Option> (new WallStreet::FixedIncome::Option::Option(strike,expiry,underlyingPrice, riskFreeRate,volatility)));
optionMap[issueDate] = optionVec;
m_optionMap[symbol] = optionMap;
}
}

Related

Using Vulkan memory allocator with Volk

I'm currently trying to use Vulkan memory allocator with the meta loader Volk
here is the link of the two: https://github.com/zeux/volk
https://gpuopen.com/vulkan-memory-allocator/
But I have trouble with creating the VmaAllocator, here is my code:
void VulkApp::Init(PipelineFlags t_Conf, entt::registry& t_reg)
{
volkInitialize();
WindowProps props = {};
props.Height = 600;
props.Width = 800;
props.Title = "Engine";
currentWindow = EngWindow::Create(props);
//Create all physical, logical, instance for vulkan
Prepare();
VolkDeviceTable test;
volkLoadDeviceTable(&test, m_LogicalDevice->GetVkDevice());
VmaAllocatorCreateInfo allocatorCreateInfo = {};
allocatorCreateInfo.vulkanApiVersion = VK_API_VERSION_1_2;
allocatorCreateInfo.physicalDevice = m_PhysicalDevice->GetVkPhysicalDevice();
allocatorCreateInfo.device = m_LogicalDevice->GetVkDevice();
allocatorCreateInfo.instance = m_Instance->GetRawVkInstance();
allocatorCreateInfo.pVulkanFunctions = reinterpret_cast<const VmaVulkanFunctions*> (&test);
VmaAllocator allocator;
vmaCreateAllocator(&allocatorCreateInfo, &allocator);
BuildRenderPipelines(t_Conf, t_reg);
}
void VulkApp::Prepare()
{
m_Instance = std::make_unique<VulkInst>();
volkLoadInstance(m_Instance->GetRawVkInstance());
currentWindow->CreateSurface(m_Instance->GetRawVkInstance(), &m_Surface);
m_PhysicalDevice = std::make_unique<PhysicalDevice>(*m_Instance);
m_LogicalDevice = std::make_unique<LogicalDevice>(*m_Instance, *m_PhysicalDevice, m_Surface);
volkLoadDevice(m_LogicalDevice->GetVkDevice());
m_SwapChain = std::make_unique<SwapChain>(ChooseSwapExtent(), *m_LogicalDevice, *m_PhysicalDevice, m_Surface);
GraphicsHelpers::CreateCommandPool(m_CommandPool, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT); //TODO: added Transient bit
CreateFrameSyncResources();
/*
Create Camera
*/
BuildSwapChainResources();
}
I don't have any error when i build, but when i execute, the VmaCreateAllocator return an error:
Exception raised at 0x00007FFAB0CD836B (VkLayer_khronos_validation.dll) in My_Game.exe : 0xC0000005 : access violation reading location 0x0000000000000120.
Not very useful, but it stops on the line 14082 of the file vk_mem_alloc.h:
(*m_VulkanFunctions.vkGetPhysicalDeviceMemoryProperties)(m_PhysicalDevice, &m_MemProps);
The program check all the vulkan validation function so my vulkan function table must be good. But still the allocation fail.
I'm sorry i don't put a 'minimal' code, but with vulkan, even the minimum is really long. So, as a first test, maybe some of you have an insight of the error?
If you use a loader like Volk, you need to provide all memory related Vulkan function pointers used by VMA yourself.
This is done via the pVulkanFunctions member of the VmaAllocatorCreateInfo structure.
So when creating your VmaAllactor you set the function pointer in that to those fetched via Volk like this:
VmaVulkanFunctions vma_vulkan_func{};
vma_vulkan_func.vkAllocateMemory = vkAllocateMemory;
vma_vulkan_func.vkBindBufferMemory = vkBindBufferMemory;
vma_vulkan_func.vkBindImageMemory = vkBindImageMemory;
vma_vulkan_func.vkCreateBuffer = vkCreateBuffer;
vma_vulkan_func.vkCreateImage = vkCreateImage;
vma_vulkan_func.vkDestroyBuffer = vkDestroyBuffer;
vma_vulkan_func.vkDestroyImage = vkDestroyImage;
vma_vulkan_func.vkFlushMappedMemoryRanges = vkFlushMappedMemoryRanges;
vma_vulkan_func.vkFreeMemory = vkFreeMemory;
vma_vulkan_func.vkGetBufferMemoryRequirements = vkGetBufferMemoryRequirements;
vma_vulkan_func.vkGetImageMemoryRequirements = vkGetImageMemoryRequirements;
vma_vulkan_func.vkGetPhysicalDeviceMemoryProperties = vkGetPhysicalDeviceMemoryProperties;
vma_vulkan_func.vkGetPhysicalDeviceProperties = vkGetPhysicalDeviceProperties;
vma_vulkan_func.vkInvalidateMappedMemoryRanges = vkInvalidateMappedMemoryRanges;
vma_vulkan_func.vkMapMemory = vkMapMemory;
vma_vulkan_func.vkUnmapMemory = vkUnmapMemory;
vma_vulkan_func.vkCmdCopyBuffer = vkCmdCopyBuffer;
And then pass those to the create info:
VmaAllocatorCreateInfo allocator_info{};
...
allocator_info.pVulkanFunctions = &vma_vulkan_func;

ColdFusion - Reading in lots of images

What is the most efficient way of reading in lots of images in CF / Railo and checking their width and height?
In my app, I need to typically read in about 20 images + and at the moment this takes up to 14 seconds to complete. A bit too long really.
theImageRead = ImageNew(theImageSrc);
if ( imageGetWidth(theImageRead) > 100 ) {
writeOutput('<img src="' & theImageSrc & '" />');
}
Images are read from a list of absolute URL's. I need to get images specified over a certain dimension.
If there's a quicker solution to this then I'd love to get your insight. Perhaps underlying java methods?
I am also using jSoup if there's anything in that which could help.
Thanks,
Michael.
I don't believe there's any way to determine the pixel dimensions of an image without reading the bytes and creating an image object. The main bottleneck here will be the http request overhead.
that said there are a few ways to speed up what you're trying to do.
use threads to concurrently request images, then when all threads have finished processing output the images.
If you display the same image or set of images more than once cache it. If you don't want to cache the actually image you can cache the metadata to avoid having to perform a http request for every image.
decide if you need to output all the images to the page immediately, or could some or all of these be deferred and loaded via and ajax request
I have written this utility function quite a while ago (it runs on older ColdFusion versions, too). Maybe it helps.
Note that this requires the Java Advanced Imaging Image I/O Tools (Jai-imageio). Download the .jar and put it in your class path (restarting CF is necessary).
/**
* Reads basic properties of many types of images. Values are
* returned as a struct consisting of the following elements:
*
* Property names, their types and default values:
* ImgInfo.width = 0 (pixels)
* ImgInfo.height = 0 (pixels)
* ImgInfo.size = 0 (bytes)
* ImgInfo.isGrayscale = false (boolean)
* ImgInfo.isFile = false (boolean)
* ImgInfo.success = false (boolean)
* ImgInfo.error = "" (string)
*
* #param FilePath Physical path to image file.
* #return A struct, as described.
*/
function GetImageProperties(FilePath) {
var ImgInfo = StructNew();
var jImageIO = CreateObject("java", "javax.imageio.ImageIO");
var jFile = CreateObject("java", "java.io.File").init(FilePath);
var jBufferedImage = 0;
var jColorSpace = 0;
ImgInfo.width = "";
ImgInfo.height = "";
ImgInfo.fileSize = 0;
ImgInfo.isGrayscale = false;
ImgInfo.isFile = jFile.isFile();
ImgInfo.success = false;
ImgInfo.error = "";
try {
jBufferedImage = jImageIO.read(jFile);
ImgInfo.fileSize = jFile.length();
ImgInfo.width = jBufferedImage.getWidth();
ImgInfo.height = jBufferedImage.getHeight();
jColorSpace = jBufferedImage.getColorModel().getColorSpace();
ImgInfo.isGrayscale = (jColorSpace.getType() eq jColorSpace.TYPE_GRAY);
ImgInfo.success = true;
}
catch (any ex) {
ImgInfo.error = ToString(ex);
}
jImageIO = JavaCast("null", "");
jFile = JavaCast("null", "");
jBufferedImage = JavaCast("null", "");
jColorSpace = JavaCast("null", "");
return ImgInfo;
}
Use like:
imageInfo = GetImageProperties(theImageSrc);
if (imageInfo.success and imageInfo.width > 100)
writeOutput('<img src="#HTMLEditFormat(theImageSrc)#" />');
}

Windows Phone 7 Consuming Webservice WSDL

Ok I have written some basic generic webservices before but I have never tried to consume a 3rd party one.
The one I am trying to consume is
http://opendap.co-ops.nos.noaa.gov/axis/webservices/predictions/wsdl/Predictions.wsdl
I am not getting any results back from this what so ever and cannot figure out why.
More odd is it is not even reaching PredictionsClient_getPredictionsAndMetadataCompleted when I put a break point in the code it doesn't even reach it.
Any suggestions would be greatly appreciated
public void Bouy(double meters)
{
PredictionService.Parameters PredictionParams = new PredictionService.Parameters();
PredictionService.PredictionsPortTypeClient PredictionsClient = new PredictionService.PredictionsPortTypeClient();
GeoCoordinateWatcher gc = new GeoCoordinateWatcher(GeoPositionAccuracy.Default);
//gc.Position.Location.Latitude, gc.Position.Location.Longitude
GeoCoordinate myLocation = new GeoCoordinate(27.931631,-82.802582);
foreach (var bl in BouyLocation.GetAll())
{
GeoCoordinate otherLocation = new GeoCoordinate(bl.Lat, bl.Lon);
PredictionParams.beginDate = DateTime.Now.ToString("yyyyMMdd");
PredictionParams.endDate = DateTime.Now.AddDays(1.0).ToString("yyyyMMdd");
PredictionParams.stationId = bl.LocationID;
PredictionParams.timeZone = 0;
PredictionParams.unit = 1;
PredictionParams.dataInterval = 6;
PredictionsClient.getPredictionsAndMetadataCompleted += new EventHandler<PredictionService.getPredictionsAndMetadataCompletedEventArgs>(PredictionsClient_getPredictionsAndMetadataCompleted);
PredictionsClient.getPredictionsAndMetadataAsync(PredictionParams);
double mymeters = myLocation.GetDistanceTo(otherLocation);
if (mymeters < meters)
{
TextBlock DynTextBlock = new TextBlock
{
Name = "Appearance" + bl.LocationID,
Text = bl.LocationName + PredictionResult,
TextWrapping = System.Windows.TextWrapping.Wrap,
Margin = new Thickness(12, -6, 12, 0),
Style = (Style)Resources["PhoneTextSubtleStyle"]
};
DynamicAppearance.Children.Add(DynTextBlock);
this.nearByLocations.Add(new BouyLocationModel() { LocationName = bl.LocationName, LocationID = bl.LocationID, Lat = bl.Lat, Lon = bl.Lon });
}
}
var test = nearByLocations;
}
void PredictionsClient_getPredictionsAndMetadataCompleted(object sender, PredictionService.getPredictionsAndMetadataCompletedEventArgs e)
{
string err = e.Error.ToString();
PredictionResult = e.Result.ToString();
}
Loooking at the code you have here I think that you have used the importing of a ServiceReference to auto build the classes for you?
Unfortunately I have found that this is rather temperamental on WP7 and the only way I actually got it to work was when I connected it to a Microsoft WCF service. Connecting to anything else just doesn't work.
If you do google searches there are various pages talking about the fact it doesn't work and ways around it (which I couldn't get to work).
However, there are ways around it but it isn't as simple as the auto-generated stuff. Basically you do things manually.
Although there are other ways to manually create the web service what I did was follow the information in the following which worked well: http://zetitle.wordpress.com/2010/10/14/using-reactive-extensions-with-webrequest/
You will need to parse the response yourself but XML to LINQ works really well for this.
Hope that helps, or maybe someone will have the solution as it is something I am interested in knowing how to get working too

Dynamics GP Web Services: SalesInvoice Creation with Lot Allocation

I'm trying to use the following code to create a new SalesInvoice based on an existing SalesOrder:
SalesInvoice invoice = new SalesInvoice();
invoice.DocumentTypeKey = new SalesDocumentTypeKey { Type = SalesDocumentType.Invoice };
invoice.CustomerKey = originalOrder.CustomerKey;
invoice.BatchKey = originalOrder.BatchKey;
invoice.Terms = new SalesTerms { DiscountTakenAmount = new MoneyAmount { Value = 0, Currency = "USD", DecimalDigits = 2 }, DiscountAvailableAmount = new MoneyAmount { Value = 0, Currency = "USD", DecimalDigits = 0 } };
invoice.OriginalSalesDocumentKey = originalOrder.Key;
List<SalesInvoiceLine> lineList = new List<SalesInvoiceLine>();
for (int i = 0; i < originalOrder.Lines.Length; i++)
{
SalesInvoiceLine line = new SalesInvoiceLine();
line.ItemKey = originalOrder.Lines[i].ItemKey;
line.Key = new SalesLineKey { LineSequenceNumber = originalOrder.Lines[i].Key.LineSequenceNumber; }
SalesLineLot lot = new SalesLineLot();
lot.LotNumber = originalOrder.Lines[i].Lots[0].LotNumber;
lot.Quantity = new Quantity { Value = 2200 };
lot.Key = new SalesLineLotKey { SequenceNumber = originalOrder.Lines[i].Lots[0].Key.SequenceNumber };
line.Lots = new SalesLineLot[] { lot };
line.Quantity = new Quantity { Value = 2200 };
lineList.Add(line);
}
invoice.Lines = lineList.ToArray();
DynamicsWS.CreateSalesInvoice(invoice, DynamicsContext, DynamicsWS.GetPolicyByOperation("CreateSalesInvoice", DynamicsContext));
When executed, I receive the following error:
SQL Server Exception: Operation expects a parameter which was not supplied.
And the more detailed exception from the Exception Console in Dynamics:
Procedure or function 'taSopLotAuto' expects parameter '#I_vLNITMSEQ',
which was not supplied.
After a considerable amount of digging through Google, I discovered a few things.
'taSopLotAuto' is an eConnect procedure within the Sales Order Processing component that attempts to automatically fill lots. I do not want the lots automatically filled, which is why I try to fill them manually in the code. I've also modified the CreateSalesInvoice policy from Automatic lot fulfillment to Manual lot fulfillment for the GP web services user, but that didn't change which eConnect procedure was called.
'#I_vLNITMSEQ' refers to the LineSequenceNumber. The LineSequenceNumber and SequenceNumber (of the Lot itself) must match. In my case they are both the default: 16384. Not only is this parameter set in the code above, but it also appears in the SOAP message that the server attempted to process - hardly "not supplied."
I can create an invoice sans line items without a hitch, but if I add line items it fails. I do not understand why I am receiving an error for a missing parameter that is clearly present.
Any ideas on how to successfully create a SalesInvoice through Dynamics GP 10.0 Web Services?
Maybe you mess to add the line key to the lot:
lot.Key = new SalesLineKey();
lot.Key.SalesDocumentKey = new SalesDocumentKey();
lot.Key.SalesDocumentKey.Id = seq.ToString();

WMI performance query

I am having an issue with a WMI query.
I use a WMI query to search and resume an instance in BizTalk.
When there are not that many instances (so when the data isn't that much) the query performs pretty good.
But when the data is large (about 3000 instances) the query takes about 6 - 10 seconds to execute, and this isn't tolerable.
Code is as following:
string query = "SELECT * FROM MSBTS_ServiceInstance WHERE InstanceID = \"" + OrchestrationId + "\"";
ManagementObjectSearcher searcher = new ManagementObjectSearcher(new ManagementScope(#"root\MicrosoftBizTalkServer"), new WqlObjectQuery(query), null);
int count = searcher.Get().Count;
if (count > 0)
{
string[] strArray = new string[count];
string[] strArray2 = new string[count];
string[] strArray3 = new string[count];
string str2 = string.Empty;
string str3 = string.Empty;
int index = 0;
foreach (ManagementObject obj2 in searcher.Get())
{
if (str2 == string.Empty)
{
str2 = obj2["HostName"].ToString();
}
strArray2[index] = obj2["ServiceClassId"].ToString();
strArray3[index] = obj2["ServiceTypeId"].ToString();
strArray[index] = obj2["InstanceID"].ToString();
str3 = str3 + string.Format(" {0}\n", obj2["InstanceID"].ToString());
index++;
}
new ManagementObject(string.Format("root\\MicrosoftBizTalkServer:MSBTS_HostQueue.HostName=\"{0}\"", str2)).InvokeMethod("ResumeServiceInstancesByID", new object[] { strArray2, strArray3, strArray, 1 });
It's the first query (Select * from MSBS_ServiceInstance..) that takes to long when te data is getting bigger.
Any ideas how I can improve this?
The platform is Windows Server 2008 Enterprise..
Thx!
It looks like you are getting all service instances for your orchestration, not just the suspended ones.
Try adding the following to your query's where clause, so that only suspended and suspended-not-resumable service instances are returned:
and (ServiceStatus = 4 or ServiceStatus = 16)
Thank you for the replies.
The reason I got that many suspended instances sometimes is by design.
Whenever a message isn't in sequence, the orchestration gets suspended until the previous message went through.
I found another way to resume the instances using the BizTalkOperations class that is installed with BizTalk:
BizTalkOperations operations = new BizTalkOperations(dataSource, initialCatalog);
foreach (Guid id in instanceIds)
{
operations.ResumeInstance(id);
}
This code is much more performant then the WMI code (and less code ^^) :)
Thanks