I usually use sysconfig(_SC_CLK_TCK) in linux to get the clock rate (which always returns 100). The problem is I want to use dhrystone benchmark with Atari Mint (TOS). I installed atari mint on an emulator called ARanyM. I used sysconfig(_SC_CLK_TCK) here also but it return something like 4294967295 (this actually all 1 value in 32-bit)
Does any body has any suggestions ?
With Linux I use:
#include <time.h>
double theseSecs = 0.0;
double startSecs = 0.0;
double secs;
double CPUsecs = 0.0;
double CPUutilisation = 0.0;
double answer = 0;
clock_t starts;
void start_CPU_time()
{
starts = clock();;
return;
}
void end_CPU_time()
{
CPUsecs = (double)(clock() - starts)/(double)CLOCKS_PER_SEC;
return;
}
struct timespec tp1;
void getSecs()
{
clock_gettime(CLOCK_REALTIME, &tp1);
theseSecs = tp1.tv_sec + tp1.tv_nsec / 1e9;
return;
}
void start_time()
{
getSecs();
startSecs = theseSecs;
return;
}
void end_time()
{
getSecs();
secs = theseSecs - startSecs;
return;
}
void calculate()
{
int i, j;
for (i=1, i<1000001; i++)
{
for (i=j, j<1000001; j++)
{
answer = answer * (float)i / 1000000.0;
}
}
}
void main()
{
start_time();
start_CPU_time();
calculate();
end_time();
end_CPU_time();
CPUutilisation = CPUsecs / secs / 100.0;
printf"/n Answer %8.3f, Elapsed Time %7.4f, CPU Time %7.4f,
CPU Utilisation %8.4f/n, answer, secs, CPUsecs, CPUutilisation);
}
Related
I am working on a project of sound source localization and want to lit an individual ws2812 Led in the direction of the sound source.
I came across an expansion software package x-cube-memsmic1 (https://www.st.com/en/embedded-software/x-cube-memsmic1.html) which uses Acoustic SL library to estimate the angle of the sound source and send the angle along with some other things to PC via USB. The description says that the audio_application.c and usbd_audio_if.c contains some functions to get the angle from the source and send it.
Now I don't know which function does this and how?
Can someone tell me how can I get that specific function so I can put it in main loop?
Thanks
Viki
#include "audio_application.h"
#include "acoustic_sl.h"
uint16_t PDM_Buffer[((((AUDIO_IN_CHANNELS * AUDIO_IN_SAMPLING_FREQUENCY) / 1000) * MAX_DECIMATION_FACTOR) / 16)* N_MS ];
/* Private variables ---------------------------------------------------------*/
/*Handler and Config structure for Source Localization*/
AcousticSL_Handler_t libSoundSourceLoc_Handler_Instance;
AcousticSL_Config_t libSoundSourceLoc_Config_Instance;
volatile int16_t SOURCE_Angle_Value = 0;
volatile uint16_t SOURCE_Enable_Value = 1;
extern UART_HandleTypeDef UartHandle;
volatile int32_t result[2];
static uint16_t PCM_Buffer[AUDIO_IN_CHANNELS * AUDIO_IN_SAMPLING_FREQUENCY / 1000];
void CCA02M2_AUDIO_IN_HalfTransfer_CallBack(uint32_t Instance)
{
UNUSED(Instance);
AudioProcess();
}
void CCA02M2_AUDIO_IN_TransferComplete_CallBack(uint32_t Instance)
{
UNUSED(Instance);
AudioProcess();
}
void AudioProcess(void)
{
if (CCA02M2_AUDIO_IN_PDMToPCM(CCA02M2_AUDIO_INSTANCE, (uint16_t *)PDM_Buffer, PCM_Buffer) != BSP_ERROR_NONE)
{
Error_Handler();
}
if (AcousticSL_Data_Input((int16_t *)&PCM_Buffer[BOTTOM_LEFT_MIC], (int16_t *)&PCM_Buffer[TOP_RIGHT_MIC],
(int16_t *)&PCM_Buffer[BOTTOM_RIGHT_MIC], (int16_t *)&PCM_Buffer[TOP_LEFT_MIC], &libSoundSourceLoc_Handler_Instance) == 1U)
{
SW_Task2_Start(); /*Localization Processing Task*/
}
Send_Audio_to_USB((int16_t *)PCM_Buffer, AUDIO_IN_SAMPLING_FREQUENCY / 1000 * AUDIO_IN_CHANNELS);
}
void Audio_Libraries_Init(void)
{
__IO uint32_t error_value = 0;
/* Enable CRC peripheral to unlock the library */
__CRC_CLK_ENABLE();
/*Setup Source Localization static parameters*/
libSoundSourceLoc_Handler_Instance.channel_number = 4;
libSoundSourceLoc_Handler_Instance.M12_distance = DIAGONAL;
libSoundSourceLoc_Handler_Instance.M34_distance = DIAGONAL;
libSoundSourceLoc_Handler_Instance.sampling_frequency = AUDIO_IN_SAMPLING_FREQUENCY;
libSoundSourceLoc_Handler_Instance.algorithm = ACOUSTIC_SL_ALGORITHM_GCCP;
libSoundSourceLoc_Handler_Instance.ptr_M1_channels = 4;
libSoundSourceLoc_Handler_Instance.ptr_M2_channels = 4;
libSoundSourceLoc_Handler_Instance.ptr_M3_channels = 4;
libSoundSourceLoc_Handler_Instance.ptr_M4_channels = 4;
libSoundSourceLoc_Handler_Instance.samples_to_process = 512;
(void)AcousticSL_getMemorySize(&libSoundSourceLoc_Handler_Instance);
libSoundSourceLoc_Handler_Instance.pInternalMemory = (uint32_t *)malloc(libSoundSourceLoc_Handler_Instance.internal_memory_size);
error_value += AcousticSL_Init(&libSoundSourceLoc_Handler_Instance);
/*Setup Source Localization dynamic parameters*/
libSoundSourceLoc_Config_Instance.resolution = 10;
libSoundSourceLoc_Config_Instance.threshold = 24;
error_value += AcousticSL_setConfig(&libSoundSourceLoc_Handler_Instance, &libSoundSourceLoc_Config_Instance);
/*Error Management*/
if (error_value != 0U)
{
Error_Handler();
}
/*Malloc Failure*/
if (libSoundSourceLoc_Handler_Instance.pInternalMemory == NULL)
{
Error_Handler();
}
}
void SW_IRQ_Tasks_Init(void)
{
HAL_NVIC_SetPriority((IRQn_Type)EXTI1_IRQn, 0x0D, 0);
HAL_NVIC_EnableIRQ((IRQn_Type)EXTI1_IRQn);
HAL_NVIC_SetPriority((IRQn_Type)EXTI2_IRQn, 0x0E, 0);
HAL_NVIC_EnableIRQ((IRQn_Type)EXTI2_IRQn);
}
void SW_Task1_Callback(void)
{
}
void SW_Task2_Callback(void)
{
(void)AcousticSL_Process((int32_t *)&result, &libSoundSourceLoc_Handler_Instance);
if (result[0] == ACOUSTIC_SL_NO_AUDIO_DETECTED)
{
result[0] = -1;
}
if (result[0] != -1)
{
char output[4];
int32_t n = sprintf(output, "%li", (int32_t)result[0]);
(void)HAL_UART_Transmit(&UartHandle, (uint8_t *)" ", 4, 0xFFFF);
(void)HAL_UART_Transmit(&UartHandle, (uint8_t *)"\r", 1, 0xFFFF);
(void)HAL_UART_Transmit(&UartHandle, (uint8_t *)output, (uint16_t)n, 0xFFFF);
}
}
void SW_Task1_Start(void)
{
HAL_NVIC_SetPendingIRQ(EXTI1_IRQn);
}
void SW_Task2_Start(void)
{
HAL_NVIC_SetPendingIRQ(EXTI2_IRQn);
}
void Error_Handler(void)
{
while (1);
}
Can you help me about the code below.
Is it writing 1 to the data memory or to the internal memory.
there are only 32 internal registers
The processor is 32 bit risc-v based
thanks in advance
#include "string.h"
#define DEBUG_IF_ADDR 0x00002010
void bubble_sort(int* arr, int len)
{
int sort_num;
do
{
sort_num = 0;
for(int i=0;i<len-1;i++)
{
if(*(arr+i) > *(arr+i+1))
{
int tmp = *(arr+i);
*(arr+i) = *(arr+i+1);
*(arr+i+1) = tmp;
sort_num++;
}
}
}
while(sort_num!=0);
}
int main()
{
int unsorted_arr[] = {195,14,176,103,54,32,128};
int sorted_arr[] = {14,32,54,103,128,176,195};
bubble_sort(unsorted_arr,7);
int *addr_ptr = DEBUG_IF_ADDR;
if(memcmp((char*) sorted_arr, (char*) unsorted_arr, 28) == 0)
{
//success
*addr_ptr = 1;
}
else
{
//failure
*addr_ptr = 0;
}
return 0;
}
I want to use multithread programming with Arduino.
I wrote some code ato update the variable tempsPose but it doesn't work (the led blinks always at the same speed).
How can I change the following code in order to update tempsPose variable in the function blinkled13 when this variable is mofified in the loop function?
#include <Thread.h>
Thread myThread = Thread();
int ledPin = 13;
volatile int tempsPose ;
void blinkLed13()
{
\\i would like the value of 'tempspose' to be updated
\\ when the value of the variable changes in the blinkLed13 function
while(1){
digitalWrite(ledPin, HIGH);
delay(tempsPose);
digitalWrite(ledPin, LOW);
delay(tempsPose);
}
}
void setup() {
tempsPose = 100;
pinMode(13,OUTPUT);
Serial.begin(9600);
myThread.onRun(blinkLed13);
if(myThread.shouldRun())
myThread.run();
}
void loop() {
for(int j=0; j<100; j++){
delay(200);
\\some code which change the value of 'tempsPose'
\\this code is pseudo code
tempsPose = tempsPose + 1000;
}
}
Examples are all "one-shot" (no infinite loops) and the code if (thread.shouldRun()) thread.run(); is inside of loop(). So I suppose it won't get into the loop() at all in your case.
For example more interactive code ('+' adds 100ms, '-' substracts 100ms):
#include <Thread.h>
Thread myThread = Thread();
int ledPin = 13;
volatile int tempsPose;
void blinkLed13() {
// i would like the value of 'tempspose' to be updated
// when the value of the variable changes in the blinkLed13 function
static bool state = 0;
state = !state;
digitalWrite(ledPin, state);
Serial.println(state ? "On" : "Off");
}
void setup() {
tempsPose = 100;
pinMode(13,OUTPUT);
Serial.begin(9600);
myThread.onRun(blinkLed13);
myThread.setInterval(tempsPose);
}
void loop() {
if(myThread.shouldRun()) myThread.run();
if (Serial.available()) {
uint8_t ch = Serial.read(); // read character from serial
if (ch == '+' && tempsPose < 10000) { // no more than 10s
tempsPose += 100;
myThread.setInterval(tempsPose);
} else if (ch == '-' && tempsPose > 100) { // less than 100ms is not allowed here
tempsPose -= 100;
myThread.setInterval(tempsPose);
}
Serial.println(tempsPose);
}
}
I need to measure performance of a function that compares two strings. My task is to write it in Java and C and compare execution time. For testing purposes I generated a txt file with 100000 random strings varying from 100 to 200 characters each. Using them I invoke comparision function 20'000'000 times. In Java it takes ~500ms while in C the execution time is 0ms (Im doing exactly the same tests on exaclty the same data in both languages). Even if I increase it to 20'000'000'000 calls in C, it still measures 0ms duration. How is it possible? Am I missing something important?
implementaton in Java
public class StringComparer {
public static boolean compareStrings(String string1, String string2) {
if(string1.length() != string2.length()) {
return false;
}
for (int i = 0; i < string1.length(); i++) {
if(string1.charAt(i) != string2.charAt(i)) {
return false;
}
}
return true;
}
}
implementation in C
bool string_compare(char* s1, char* s2)
{
int i = 0;
while (s1[i] != NULL && s1[i] == s2[i])
i++;
return s1[i] == s2[i];
}
This is the code I use to test performance in C
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <windows.h>
#define NUMBER_OF_WORDS 100000
#define MAX_WORD_LENGTH 200
long long milliseconds_now() {
static LARGE_INTEGER s_frequency;
BOOL s_use_qpc = QueryPerformanceFrequency(&s_frequency);
if (s_use_qpc) {
LARGE_INTEGER now;
QueryPerformanceCounter(&now);
return (1000LL * now.QuadPart) / s_frequency.QuadPart;
}
else {
return GetTickCount();
}
}
int main()
{
char* fileName = "tests.txt";
FILE *file = fopen(fileName, "r");
char* words[NUMBER_OF_WORDS];
long long i, j;
for (i = 0; i < NUMBER_OF_WORDS; i++) {
words[i] = (char*)malloc((MAX_WORD_LENGTH + 1) * sizeof(char));
fgets(words[i], MAX_WORD_LENGTH + 1, file);
}
long long repeats = 10000000000 / NUMBER_OF_WORDS;
long long start = milliseconds_now();
for (i = 0; i < repeats; i++)
{
for (j = 0; j < NUMBER_OF_WORDS - 1; j++)
{
;
}
}
long long loopDuration = milliseconds_now() - start;
start = milliseconds_now();
for (i = 0; i < repeats; i++)
{
for (j = 0; j < NUMBER_OF_WORDS - 1; j++)
{
string_compare(words[j], words[j + 1]); //compare different strings
string_compare(words[j], words[j]); //compare the same strings
}
}
long long customFunctionDuration = milliseconds_now() - start;
printf("Loop duration: %lld\n", loopDuration);
printf("Custom function duration: %lld - %lld = %lld ms", customFunctionDuration, loopDuration, customFunctionDuration - loopDuration);
return 0;
}
Your code's observable behavior is precisely the same as code that does nothing at all. You need to make the result of the string comparisons part of your program's observable behavior so they can't be optimized to nothing. Try tallying the number of times strings match and the number of times the strings don't match and outputting that number.
I'm trying to transfer a command line code that I have to a more visual program with a
GUI to enable easier use. The original code was in C++, so I'm using Visual C++ that is
available in Visual Studio Express 2012, but I have problems understanding the "new"
managed C++/CLI way of handling objects. Being new to CLI and managed C++, I was wondering
if someone can explain what I am doing wrong, and why it doesn't work. Now here is a
description of the code and the problem.
The program is essentially an optimization program:
There are multiple boxes (modes) in a system, each mode, depending on its type has a
few numerical coefficients that control its behavior and the way it responds to outside
excitation.
The program asks the user to specify the number of boxes and the type of each box.
Then tries to find the numerical coefficients that minimize the difference between
the system response with those obtained experimentally.
So, the UI has means for user to open the experimental result files, specify the number
of modes, and specify the type of each mode. Then, the user can initiate the processing
function by clicking on a start button, that initiates a background worker.
Following the example given in MSDN, I created a class that performs the work:
ref class curveFit
{
public: ref class CurrentState{
public:
int percentage;
int iterationNo;
int stage;
bool done;
multimode systemModel;
};
public:
int modes;
int returncode;
array<double> ^expExcitations;
array<double> ^expResults;
multimode systemModel;
private:
void fcn(int, int, double*, double*, int*);
double totalError(std::vector<double> &);
public:
delegate void fcndelegate(int, int, double*, double*, int*);
public:
curveFit(void);
curveFit^ fit(System::ComponentModel::BackgroundWorker^, System::ComponentModel::DoWorkEventArgs^, Options^);
};
multimode is just a container class: a list of different boxes.
ref class multimode
{
private:
Collections::Generic::List<genericBoxModel ^>^ models;
int modes;
public:
multimode(void);
multimode(const multimode%);
int modeNo(void);
void Add(genericBoxModel^);
void Clear();
genericBoxModel^ operator[](int);
multimode% operator=(const multimode%);
double result(double);
bool isValid();
std::vector<double> MapData();
void MapData(std::vector<double> &);
};
multimode::multimode(void)
{
models = gcnew Collections::Generic::List<genericBoxModel ^>();
modes = 0;
}
multimode::multimode(const multimode% rhs)
{
models = gcnew Collections::Generic::List<genericBoxModel ^>();
for(int ind = 0; ind < rhs.modes; ind++)
models->Add(rhs.models[ind]);
modes = rhs.modes;
}
int multimode::modeNo(void)
{
return modes;
}
void multimode::Add(genericBoxModel^ model)
{
models->Add(model);
modes++;
}
void multimode::Clear()
{
models->Clear();
modes = 0;
}
genericBoxModel^ multimode::operator[](int ind)
{
return models[ind];
}
multimode% multimode::operator=(const multimode% rhs)
{
models->Clear();
for(int ind = 0; ind < rhs.modes; ind++)
models->Add(rhs.models[ind]);
modes = rhs.modes;
return *this;
}
double multimode::result(double excitation)
{
double temp = 0.0;
for(int ind = 0; ind < modes; ind++)
temp += models[ind]->result(excitation);
return temp;
}
bool multimode::isValid()
{
bool isvalid = true;
if(modes < 1)
return false;
for(int ind = 0; ind < modes; ind++)
isvalid = (isvalid && models[ind]->isValid());
return isvalid;
}
std::vector<double> multimode::fullMap()
{
//Map the model coefficients to a vector of doubles
...
}
void multimode::fullMap(std::vector<double> &data)
{
//Map a vector of doubles to the model coefficients
...
}
and genericBoxModel is an abstract class that all box models are based on.
The curvefit::fit function does the optimization based on the options passed to it:
curveFit^ curveFit::fit(System::ComponentModel::BackgroundWorker^ worker, System::ComponentModel::DoWorkEventArgs^ e, Options^ opts)
{
fcndelegate^ del = gcnew fcndelegate(this, &curveFit::fcn);
std::vector<double> data;
CurrentState^ state = gcnew CurrentState;
state->done = false;
state->stage = 0;
state->percentage = 0;
state->systemModel = systemModel;
worker->ReportProgress(state->percentage, state);
switch(opts->optimizationMethod)
{
case 0:
while(iterationNo < maxIterations)
{
data = systemModel.MapData();
OptimizationMethod0::step(some_parameters, data, (optmethods::costfunction)Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(del).ToPointer());
systemModel.MapData(data);
iterationNo++;
state->percentage = 0;
state->systemModel = systemModel;
worker->ReportProgress(state->percentage, state);
}
...
}
}
I'm passing the system model inside the state so that I can display the results of the
latest step on the screen, which doesn't work, but that is another question :-)
The start button calls the curvefit::fit function after initializing the system model:
private: System::Void btnStart_Click(System::Object^ sender, System::EventArgs^ e) {
systemModel.Clear();
for(int mode = 0; mode < modes; mode++)
{
switch(model)
{
case 0:
systemModel.Add(gcnew model0);
systemModel[mode]->coefficients[0] = 100.0 / double(mode + 1);
...
break;
...
}
}
btnStart->Enabled = false;
stStatusText->Text = "Calculating!";
Application::UseWaitCursor = true;
curveFit^ cf = gcnew curveFit;
fitCurve->RunWorkerAsync(cf);
}
private: System::Void fitCurve_DoWork(System::Object^ sender, System::ComponentModel::DoWorkEventArgs^ e) {
System::ComponentModel::BackgroundWorker^ worker;
worker = dynamic_cast<System::ComponentModel::BackgroundWorker^>(sender);
curveFit^ cf = safe_cast<curveFit^>(e->Argument);
cf->expExcitations = gcnew array<double>(expExcitations.Count);
expExcitations.CopyTo(cf->expExcitations);
cf->expResults = gcnew array<double>(expResults.Count);
expResults.CopyTo(cf->expResults);
cf->systemModel = systemModel;
cf->modes = modes;
e->Result = cf->fit(worker, e, options);
}
This works perfectly! But, in order to make the optimization process faster and more
successful, I wanted to use the results of previous optimizations as the initial guess
for the next run (if possible):
multimode oldmodel(systemModel);
systemModel.Clear();
for(int mode = 0; mode < modes; mode++)
{
switch(model)
{
case 0:
if(mode < oldmodel.modeNo() && oldmodel.isValid() && (oldmodel[mode]->model == 0))
systemModel.Add(oldmodel[mode]);
else
{
systemModel.Add(gcnew model0);
systemModel[mode]->coefficients[0] = 100.0 / double(mode + 1);
...
}
break;
...
Now, my problem is, after this change, it seems that the messages don't get passed
correctly: the first time the start button is clicked everything functions as it should,
but from then on, if the statement systemModel.Add(oldmodel[mode]); gets executed,
results remain the same as the initial guesses, and don't get updated after the fit
function is called.
So, why should these two lines(Add(oldmodel[mode]) and Add(gcnew model0)) give
such different results?