Monday, May 12, 2014

Preventing Pointer Aliasing in C (for Scientific Computing Optimization Purposes)

The issue of pointer aliasing in C for those working with Scientific Computing code is probably a familiar issue. Pointer aliasing happens when more than one pointer refers to the same or overlapping memory region. This hurts performance in Scientific Computing code written in C. Pointer aliasing is probably the biggest issue which hurts performance of Scientific Computing code written in C compared to those written in Fortran. However, as of C99 standard, pointer aliasing can be "disabled" via the __restrict__ keyword. Most mainline C/C++ compilers supports this keyword. These are the relevant links for various mainline compilers/toolchains:

Sunday, May 11, 2014

Raspberry Pi 3G-Ethernet Router

In this post, I'm going to explain a DIY 3G-ethernet router based on Raspberry Pi. The configuration of this DIY "router" is simple:

Internet <--> USB 3G modem <-->powered USB hub <--> Raspberry Pi <--> Ethernet <--> user machine (PC/Laptop)

The purpose of this kind of router varied, depending on your needs. However, I have a very specific need in one of my setup where providing Internet connection directly from the 3G modem is not possible and only Ethernet interface can be used by the user (physical/virtual) machine.

These are what you need:
  1. A Raspberry Pi (I'm using the B revision), with Raspbian distro.
  2. A powered USB hub. This is required because most USB 3G modems are power hungry and cannot be operated reliably only via the USB connector on the Pi.
  3. A USB 3G modem. Use whatever you have, hopefully Raspbian kernel already support it. I'm using Huawei E153 USB modem which is rather not so friendly in terms of operation in Raspbian, but it works reliably nonetheless, once you know how to "switch" it into modem "mode".
  4. Ethernet cable.
  5. A user machine to test the interconnection.
  6. Internet/data plan subscription to your mobile operator or whatever works for you.
Let's start with installing the software needed for the USB 3G modem to work on Raspbian. I'm basically using the steps mentioned at The Fan Club, but modify them a bit because I'm not using wvdial. These are my modified steps:
  1. Update your Raspbian with "sudo apt-get update"
  2. Install the needed packages with "sudo apt-get install ppp usb-modeswitch"
  3. Configure the pppd configuration file according to your needs.
Now, the software installation steps to setup the DHCP server and Network Address Translation (NAT) are mostly similar to the one at Adafruit: https://learn.adafruit.com/setting-up-a-raspberry-pi-as-a-wifi-access-point/install-software, except that you should remember that the "outgoing" interface in our case is eth0, instead of wlan0 and the "incoming" interface is ppp0 instead of eth0. Therefore, I believe you can adjust the steps accordingly. Also, I found that Adafruit step to make the NAT setting permanent is not working for me. I have to modify the configuration line in /etc/network/interfaces to:

pre-up iptables-restore < /etc/iptables.ipv4.nat

instead of the one explained by Adafruit to make the NAT work permanently across reboots and shutdowns.

The next step is to connect to the Internet. These are my steps:
  1. Power on the Raspberry Pi.
  2. Unplug the 3G USB modem from the USB hub, and then plug it back again if it's previously plugged in before Raspberry Pi finished booting. This is a compatibility hack because sometimes it is required, and sometimes not.
  3. Wait until the 3G USB modem is recognized (watch syslog, i.e. tail -f /var/log/messages)
  4. Run usb_modeswitch on the modem
  5. Run pppd
  6. Watch syslog to find out whether the data connection succeeded or not, i.e. tail -f /var/log/messages 
  7. Test the connection with your user machine connected through Raspberry Pi Ethernet.
Note that step 1 to 5 must be carried out exactly as mentioned above, otherwise pppd will always fail to initialize data connection with pppd. I'm not so sure what causes it, but it seems that the modem cannot respond to the AT command(s) sent by pppd correctly, at least the command to establish data connection. I saw that through syslog.

I also run a DHCP server in my Raspberry Pi, the isc-dhcp server. The configuration files for isc-dhcp are /etc/init.d/isc-dhcp-server, /etc/default/isc-dhcp-server and /etc/dhcp/dhcpd.conf. You only need to deal with the last two config files. /etc/default/isc-dhcp-server determines which network interface(s) used to listen for DHCP client requests. /etc/dhcp/dhcpd.conf determines the network configuration, such as the IP addresses to assign to the client, DNS servers, gateway, etc. Let's have a look at my configuration files.
This is how my /etc/default/isc-dhcp-server looks like.

# Defaults for isc-dhcp-server initscript
# sourced by /etc/init.d/isc-dhcp-server
# installed at /etc/default/isc-dhcp-server by the maintainer scripts

#
# This is a POSIX shell fragment
#

# Path to dhcpd's config file (default: /etc/dhcp/dhcpd.conf).
DHCPD_CONF=/etc/dhcp/dhcpd.conf

# Path to dhcpd's PID file (default: /var/run/dhcpd.pid).
#DHCPD_PID=/var/run/dhcpd.pid

# Additional options to start dhcpd with.
#       Don't use options -cf or -pf here; use DHCPD_CONF/ DHCPD_PID instead
#OPTIONS=""

# On what interfaces should the DHCP server (dhcpd) serve DHCP requests?
#       Separate multiple interfaces with spaces, e.g. "eth0 eth1".
INTERFACES="eth0"
As you can see, isc-dhcp listens to client on the ethernet interface and the dhcpd configuration file to use is set to /etc/dhcp/dhcpd.conf. Now, let's have a look at /etc/dhcp/dhcpd.conf.
#
# Sample configuration file for ISC dhcpd for Debian
#
#

# The ddns-updates-style parameter controls whether or not the server will
# attempt to do a DNS update when a lease is confirmed. We default to the
# behavior of the version 2 packages ('none', since DHCP v2 didn't
# have support for DDNS.)
ddns-update-style none;

# option definitions common to all supported networks...
#option domain-name "example.org";
#option domain-name-servers ns1.example.org, ns2.example.org;

default-lease-time 7200;
max-lease-time 86400;

# If this DHCP server is the official DHCP server for the local
# network, the authoritative directive should be uncommented.
authoritative;

# Use this to send dhcp log messages to a different log file (you also
# have to hack syslog.conf to complete the redirection).
log-facility local7;

# .. irrelevant commented config omitted for brevity ..

# Raspberry Pi subnet - note: this is the subnet of M$ Internet Connection Sharing
# TODO: Make sure the router configuration is correct
subnet 192.168.137.0 netmask 255.255.255.0 {
  range 192.168.137.3 192.168.137.21;
  option broadcast-address 192.168.137.255;
  option routers 192.168.137.2;
  default-lease-time 7200;
  max-lease-time 86400;
  option domain-name "local";
  option domain-name-servers 8.8.8.8, 8.8.4.4;
}
As you can see, the lease time and maximum lease time configuration are consistent. I found that inconsistencies in these parameters sometimes causes isc-dhcp fails to provide valid IP addresses to the DHCP clients. So, watch-out to those parameters values.

Well, there are some more details regarding pppd, usb_modeswitch and iptables which are missing. This post is still considered beta and I'm going to update it in the not so distant future..

Saturday, March 29, 2014

OpenGL Texture is not (just) Picture

I'm a beginner in OpenGL for sure and one of the most confusing thing (read: naming convention) that has plagued me in these last two days is OpenGL texture. Contrary to the naming for functions, constants and objects used for OpenGL texture, everything related to texture on those "interfaces" don't really apply to image/picture only. It's much more general than that. OpenGL texture is basically a "lookup-table" (array) and it can store anything as long as the data type matches with the texture that you use in your code. The naming for OpenGL texture "interface" that usually implies the use of image/picture is a legacy of the past. It was used since the day of fixed-function video card and used until now to preserve API backward-compatibility--at least that's one of the reason that I'm aware of.

Anyway, these are some useful links regarding OpenGL texture:
http://www.mathematik.uni-dortmund.de/~goeddeke/gpgpu/tutorial.html#arrays1
http://www.arcsynthesis.org/gltut/Texturing/Tutorial%2014.html

Friday, March 21, 2014

Adding New Directory to CodeBlocks Code Completion

CodeBlocks (http://www.codeblocks.org) cannot enumerate all of the possible C/C++ include directories automatically in some cases. For example, when you are using 3rd party C/C++ libraries which are installed in non-standard path. At least that's the state of CodeBlocks v13.12.

Now, how do you go about adding new directories to be added to the codecompletion parser? The procedure is explained in CodeBlocks FAQ at http://wiki.codeblocks.org/index.php?title=FAQ-Settings. However, as I found out, only the second method works in CodeBlocks v13.12, i.e. only the per-project non-standard include directories (to be parsed) can be configured. These are the steps:

  1. Activate the project (either by double clicking on it in the Projects pane or right click on the project and then click "Activate")
  2. Click on the "Project | Properties" menu. 
  3. Click on the "C/C++ parser options" tab. 
  4. Add the additional include directory to be parsed by the Code Completion plugin.
  5. Click on OK.
Now, you should have code completion working in CodeBlocks editor. If it's not working yet, you might need to close the project and re-open the project again.