Question on OpenMP for multi-threaded code:
Are all global variables shared by the threads? How does one make certain global variable private to master thread?
Thanks
PS: It is a C code.
if i recall correctly
#pragma omp threadprivate
global variables are a bit tricky, if they has to be initialized, you have to use copyfirst directive (i think that is correct name). also threadprivate variables may carry a significant penalty, on some implementations variable access becomes a function call.
Related
When using the Extended Program Check, I get the following warning:
Do not declare fields and field symbols (variable name) globally.
This is from declaring global data before the selection screen. The obvious solution is that they should be declared locally in a subroutine.
If I decide to do this, the data will now be out of scope for the other subroutines, so I would end up creating something to the effect of a main() function from C or Java. This sounds like a good idea - however, events such as INITIALIZATION are not allowed to be inside of subroutines, meaning that it forces a break in scope.
Observe the sample program below:
REPORT Z_EXAMPLE.
SELECTION-SCREEN BEGIN OF BLOCK upload WITH FRAME TITLE text-H01.
PARAMETERS: p_infile TYPE rlgrap-filename LOWER CASE OBLIGATORY.
SELECTION-SCREEN END OF BLOCK upload.
AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_infile.
PERFORM main1 CHANGING p_infile.
INITIALIZATION.
PERFORM main2.
TOP-OF-PAGE.
PERFORM main3.
...
main1, main2, and main3 cannot to my knowledge pass any data to one another without global declaration. If the data is parsed from the uploaded file p_infile in main1, it cannot be accessed in main2 or main3. Aside from omitting events all together, is there any way to abide by the warning but let data be passed over events?
There are a variety of techniques - I prefer to code almost everything except for the basic selection screen handling in a separate controller class. The report simply defers to that class and calls its methods. Other than that - it's just a warning that you can ignore if you know what you're doing. Writing a program without any global variable at all will certainly not be practical - however, you should think at least twice before using global variables or attributes in a place where a method parameter would be more appropriate.
As #vwegert so rightly said, it's almost impossible to write an ABAP program that doesn't have at least a few global variables (the selection screen and events enforce that, unfortunately).
One approach is to use a controller class, another is to have a main subroutine and have it call other subroutines as required, passing values as required. I tend to favour the latter approach in a lot of cases, if only because it's easier to split the subroutines into logical groupings in separate includes (doing so with classes can sometimes be a little ugly). It really is a matter of approach though, but the key thing is reducing global variables to a minimum - unfortunately too few ABAP developers that I've encountered care about such issues.
Update
#Christian has reminded me that as of ABAP AS 7.02, subroutines are considered obsolete:
Subroutines should no longer be created in new programs for the following reasons:
The parameter interface has clear weaknesses when compared with the parameter interface of methods, such as:
positional parameters instead of keyword parameters
no genuine input parameters in pass by reference
typing is optional
no optional parameters
Every subroutine implicitly belongs to the public interface of its program. Generally this is not desirable.
Calling subroutines externally is critical with regard to the assignment of the container program to a program group in the internal session. This assignment cannot generally be defined as static.
Those are all valid points and I think in light of that, using classes for modularisation is definitely the preferred approach (and from a purely aesthetic point of view, they also "fit" better with the syntax enhancements in 7.02 and later).
JS libraries like Underscore.js and LoDash.js provide functions, usually via a global object _:
_.map(...);
_.filter(...);
Such basic functions are global functions in Python and part of the standard library:
map(...)
filter(...)
If I promoted the library functions to global functions...
window.map = _.map;
window.filter = _.filter;
map(...);
filter(...);
... what downsides would there be (other than global namespace pollution)?
Do I have to expect any performance issues?
Will it lead to errors in certain browsers? (e.g. if a built-in JS function is overwritten by a library function, which in turn relies on the native function)
Will chaining still work?
There are multiple downsides, but performance is not likely to be one of them.
What if two libraries have a map() function and the behaviors are slightly different? If they both put their map() in the global space, you won't be able to access one of them. And you might not be able to easily know that the map() you actually want has been overwritten.
By the way, map() and filter() are part of recent-ish JS implementations, but even there, they are part of the prototype of the objects that use them. So you have Array.prototype.map() and Array.prototype.filter().
Here are some reasons to avoid making lots of things like map and filter be global variables:
Naming conflicts with other code/libraries attempting to do something similar, but incompatible. If all code is using numerous global functions, then the simple definition of a single global function could completely break your app because it would be redefining such a function used for something else somewhere else in the code. This, all by itself, is a reason to use as few globals as possible. In a team project or a project using significant third party libraries, this is impossible to manage and will inevitably lead to lost productivity or, even worse, bad bugs that might not immediately be apparent.
Code modules are less self describing when a symbol is just global. Hmmm, where does the symbol map() come from. Is this built in? Is it defined locally? Is it defined by some library? It's a lot easier to know where gutils.map() comes from (from the gutils module). Large numbers of global anything is just less maintainable than breaking things into well defined modules.
There are numerous advantages to defining functions as methods on the objects on which they operate (such as ES5 .map() and .filter() being methods on the Array object rather than as generic globals). Now, it is considered bad practice to add non-standard methods to existing built-in objects (also for naming collision reasons), but adding polyfills that implement standard behavior is encouraged.
See these references for other info:
How and Why to Avoid Globals in Javascript
I've Heard Global Variables Are Bad, What Alternative Solution Should I Use?
Essential Javascript Namespacing Patterns
Javascript Namespaces and Modules
How do I declare a namespace in JavaScript?
As to the topic of performance, it should not be your first concern and will likely not even be a relevant concern in most code. It is much more important to start with a robust, maintainable coding strategy and then optimize only small pieces of code where performance is critical than to sacrifice robustness at the beginning in the name of performance.
In any tight loop where performance is criticial, you can always assign any function to a local variable to slightly improve performance and this will be faster than either a module reference or a global reference (because locals are resolved before globals).
So, if you had gUtils.map() in a module and you want to maximize performance inside a particular function, you can do this:
function x() {
var map = gUtils.map;
for (var i = 0; i < someBigNumber; i++) {
map(...);
}
}
Consider a library like this,
_ = (function(){
lib = {};
lib.function1 = function(){
//code
};
lib.function2 = function(){
this.function1();
};
//more code
return lib;
})();
if you use,
window.function2 = _.function2;
function2();
The library uses "this" operator in function2. Your way changes the scope of the function2 here. The function2() call will give an error saying "function1 is not defined".
You don't need to worry about performance; even if you add an extra layer to a symbol lookup, most modern JS engines will alias it. Nor should you worry about augmenting native objects causing exceptions - that's allowed. No, the big issue is the namespace pollution, which you seem to be a bit dismissive of.
What happens when your code runs on a newer browser that implements these functions natively? Let's say you'd written this code in 2009, and added .map() to Array.prototype. Your code would now have some big issues if someone added a new library that expected one function signature (the native one's) and got a different one (yours).
If you must do this, at least check whether the global symbol already exists, e.g.
window.map = window.map || myLib.map;
Also, make sure that any code relying on your map implementation can either signal its dependencies to a JavaScript dependency management tool like RequireJS, or that you have a robust DM system already in place, and that your native overrides are attached before any other code executes (e.g., don't put your code in an async script tag, don't defer execution until DOMContentLoaded, etc.)
Is it a way to create mutable state with modules? How can using this be a good idea? Wouldn't that kind of break the immutability idea from functional programming?
No because it's used at compile-time. It's kind of #define in C.
You can see example https://gist.github.com/mprymek/8379066 where attribute "sensors" is used to accumulate functions defined with macro "sensor". When you have all these functions accumulated, you can automatically generate function "run_all" which runs all of them. Of course all of this must be done at compile-time.
Every web development framework I've come across, including the best designed ones (Web2Py, Kohana) make use of some form of global variables to represent objects that are global within the application domain- for example, objects representing 'request' and 'response'.
On the other hand, the idea that global variables are bad is one of the fundamental axioms of programming. Indeed the now common disparagements of the singleton pattern usually point to the fact that it's nothing more than globals in disguise, as if that were explanation enough.
I'm trying to understand once and for all how globals can be so condemnable and at the same time be a seemingly indispensable part of all our web frameworks?
What is a global? Taking your text I assume you mean a variable that's declared at global scope. Such variable could be overridden by any assignment and break existing functionality.
However, in OO languages, everything is inside a class and assignment can be wrapped in gettors and settors for properties, or completely hidden behind methods. This gives a safe way of dealing with globals. Note that in proper OO languages (Java, C#, VB.NET etc) it is not possible to have global variables (sometimes a language construct suggests otherwise, but static fields in C# or modules in VB, mixins in Ruby are all wrapped in classes and thus not truly global).
A singleton, you mention it, is a special kind of global. As a designer you can control how many instances run of it. A car only needs one engine, a country only one government (or war breaks loose) and a program needs only one main thread. Globals are a necessity to programming, the real discussion should not be, do we need them, but how to solidly create and use them.
You say that request and response objects are globals in web development. They are not. They are (usually, depending on your toolset) convenience variables set in scope before your code is run. Since a web application can have multiple request objects at any given time, I think these are a poor example of a global variable. They are not (but they are usually local and a singleton to your current thread).
One important feature that you cannot cover in traditional procedural languages (like Basic, Pascal, C) is access control and thus concurrency and thread safety for global variables. In .NET for instance, any static method or property in the BCL (one could say that any static variable is global by definition) is thread-safe by design. Guidelines for user-defined static methods or properties suggest you do the same.
EDIT: the danger is with languages that allow global variables but at the same time propagate themselves as truly OO. While these are wonderful languages, it is indeed dangerous to step out of the protection of OO and create globals in for instance Perl, Python, Ruby, PHP.
I don't know exactly in what context those globals are used in web frameworks, but anything global starts to create problems as soon as you need to have solid access control. If you start to use such a global in concurrently executing program, it's quite hard to say who and when accessed and changed it. It creates so-called shared state. This makes debugging even more difficult.
Anyway, I am not really in favour of such statements. This only leads to oversimplifications. You have to weight you requirements and then decide if this or that pattern brings more positive or negative effects...
Say I have a situation where I really want to use Parallel.ForEach instead of a regular foreach loop because it's much more performant (and way cooler), but having .NET determine the degree of parallelism for me leads to disastrous effects.
Now say that I've discovered the magic number that I need to place in the ParallelOptions.MaxDegreeOfParallelism parameter so that my application is super tasty fast and not super tasty broken.
Instead of having to remember to include a ParallelOptions parameter with the magic number every time I invoke Parallel.ForEach (or any other derivative of it), is there any way to specify the degree of parallelism at the web.config level? Or some other approach where the value can be set globally and invisibly so I don't have to rely on the memory of myself and fellow developers any time we want to gain the benefits of parallelism?
The short answer is No, you can't configure this parameter using a config file, however you can still have a const variable that all your call can refer to.
You could make your own wrapper function that calls Parallel.Foreach that reads the degree from a config file or from a constant.