Per-pixel rendering operations are not particularly efficient on modern hardware. In the past, on classic game consoles and older PCs, they could be made usefully efficient because you had direct access to video RAM. On modern machines this is no longer the case.
Consequently, if you want to do per-pixel manipulation efficiently, you are better off constructing your own in-memory buffer of the pixel data (something as simple as a
char * pointing at a buffer of
4 * width * height bytes, assuming you want four-component RGBA pixels) and directly manipulating that.
At the conclusion of every frame, you then use a modern, efficient method to render this buffer to the screen. Typically, these days, that would involve updating a GPU texture with your pixel buffer and rendering a fullscreen quad with that texture mapped accordingly.
Further, when actually manipulating the pixels, it's better not to actually set each pixel individually, if possible. Most of the time you'll be rendering objects that consist of more than one pixel, and in those cases you should use specialized routines to blit the data. Focus on accessing the memory of the destination buffer (and source buffer, if you are copying a sprite) in a cache-coherent fashion. Copy entire rows of data when possible (for opaque sprites, for example, you can
memcpy the rows of the sprite).
Another technique commonly used when doing this kind of thing is to use "dirty rectangles," that is, tracking which regions have changed and only re-rendering those (the previous frame bounds of a sprite, the current frame bounds of a sprite, for example -- or their union if they overlap, as they commonly will). This will generally also involve keeping a separate buffer containing all the static background imagery in a scene, so you can then (for each dirty rectangle), blit the appropriate portion of the background into the rectangle, then do the appropriate foreground drawing.